Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/chromeos/input_method/input_method_engine_ibus.h" | |
| 6 | |
| 7 #include <map> | |
| 8 | |
| 9 #include "base/logging.h" | |
| 10 #include "base/memory/scoped_ptr.h" | |
| 11 #include "base/string_number_conversions.h" | |
| 12 #include "base/string_util.h" | |
| 13 #include "chrome/browser/chromeos/input_method/ibus_keymap.h" | |
| 14 #include "chrome/browser/chromeos/input_method/input_method_manager.h" | |
| 15 #include "chrome/browser/chromeos/input_method/input_method_util.h" | |
| 16 #include "chromeos/dbus/dbus_thread_manager.h" | |
| 17 #include "chromeos/dbus/ibus/ibus_client.h" | |
| 18 #include "chromeos/dbus/ibus/ibus_component.h" | |
| 19 #include "chromeos/dbus/ibus/ibus_engine_factory_service.h" | |
| 20 #include "chromeos/dbus/ibus/ibus_engine_service.h" | |
| 21 #include "chromeos/dbus/ibus/ibus_lookup_table.h" | |
| 22 #include "chromeos/dbus/ibus/ibus_property.h" | |
| 23 #include "chromeos/dbus/ibus/ibus_text.h" | |
| 24 #include "dbus/object_path.h" | |
| 25 | |
| 26 namespace chromeos { | |
| 27 const char* kExtensionImePrefix = "_ext_ime_"; | |
| 28 const char* kErrorNotActive = "IME is not active"; | |
| 29 const char* kErrorWrongContext = "Context is not active"; | |
| 30 const char* kCandidateNotFound = "Candidate not found"; | |
| 31 const char* kEngineBusPrefix = "org.freedesktop.IBus."; | |
| 32 | |
| 33 namespace { | |
| 34 const uint32 kIBusAltKeyMask = 1 << 3; | |
| 35 const uint32 kIBusCtrlKeyMask = 1 << 2; | |
| 36 const uint32 kIBusShiftKeyMask = 1 << 0; | |
| 37 const uint32 kIBusKeyReleaseMask = 1 << 30; | |
| 38 } | |
| 39 | |
| 40 InputMethodEngineIBus::InputMethodEngineIBus() | |
| 41 : focused_(false), | |
| 42 active_(false), | |
| 43 context_id_(0), | |
| 44 next_context_id_(1), | |
| 45 current_object_path_(0), | |
| 46 aux_text_(new ibus::IBusText()), | |
| 47 aux_text_visible_(false), | |
| 48 observer_(NULL), | |
| 49 preedit_text_(new ibus::IBusText()), | |
| 50 preedit_cursor_(0), | |
| 51 component_(new ibus::IBusComponent()), | |
| 52 table_(new ibus::IBusLookupTable()), | |
| 53 table_visible_(false), | |
| 54 weak_ptr_factory_(this) { | |
| 55 } | |
| 56 | |
| 57 void InputMethodEngineIBus::Initialize( | |
| 58 InputMethodEngine::Observer* observer, | |
| 59 const char* engine_name, | |
| 60 const char* extension_id, | |
| 61 const char* engine_id, | |
| 62 const char* description, | |
| 63 const char* language, | |
| 64 const std::vector<std::string>& layouts, | |
| 65 std::string* error) { | |
| 66 DCHECK(observer) << "Observer must not be null."; | |
| 67 | |
| 68 observer_ = observer; | |
| 69 engine_id_ = engine_id; | |
| 70 ibus_id_ = kExtensionImePrefix; | |
| 71 ibus_id_ += extension_id; | |
| 72 ibus_id_ += engine_id; | |
| 73 | |
| 74 input_method::InputMethodManager* manager = | |
| 75 input_method::InputMethodManager::GetInstance(); | |
| 76 std::string layout; | |
| 77 if (!layouts.empty()) { | |
| 78 layout = JoinString(layouts, ','); | |
| 79 } else { | |
| 80 input_method::InputMethodManager* manager = | |
| 81 input_method::InputMethodManager::GetInstance(); | |
| 82 const std::string fallback_id = | |
| 83 manager->GetInputMethodUtil()->GetHardwareInputMethodId(); | |
| 84 const input_method::InputMethodDescriptor* fallback_desc = | |
| 85 manager->GetInputMethodUtil()->GetInputMethodDescriptorFromId( | |
| 86 fallback_id); | |
| 87 layout = fallback_desc->keyboard_layout(); | |
| 88 } | |
| 89 | |
| 90 component_.reset(new ibus::IBusComponent()); | |
| 91 component_->set_name(std::string(kEngineBusPrefix) + std::string(engine_id)); | |
| 92 component_->set_description(description); | |
| 93 component_->set_author(engine_name); | |
| 94 | |
| 95 chromeos::ibus::IBusComponent::EngineDescription engine_desc; | |
| 96 engine_desc.engine_id = ibus_id_; | |
| 97 engine_desc.display_name = description; | |
| 98 engine_desc.description = description; | |
| 99 engine_desc.language_code = language; | |
| 100 engine_desc.author = ibus_id_; | |
| 101 engine_desc.layout = layout.c_str(); | |
| 102 | |
| 103 component_->mutable_engine_description()->push_back(engine_desc); | |
| 104 manager->AddInputMethodExtension(ibus_id_, engine_name, layouts, language, | |
| 105 this); | |
| 106 // If connection is avaiable, register component. If there are no connection | |
| 107 // to ibus-daemon, OnConnected callback will register component instead. | |
| 108 if (IsConnected()) | |
| 109 RegisterComponent(); | |
| 110 } | |
| 111 | |
| 112 InputMethodEngineIBus::~InputMethodEngineIBus() { | |
| 113 } | |
| 114 | |
| 115 bool InputMethodEngineIBus::SetComposition( | |
| 116 int context_id, | |
| 117 const char* text, | |
| 118 int selection_start, | |
| 119 int selection_end, | |
| 120 int cursor, | |
| 121 const std::vector<SegmentInfo>& segments, | |
| 122 std::string* error) { | |
| 123 if (!active_) { | |
| 124 *error = kErrorNotActive; | |
| 125 return false; | |
| 126 } | |
| 127 if (context_id != context_id_ || context_id_ == -1) { | |
| 128 *error = kErrorWrongContext; | |
| 129 return false; | |
| 130 } | |
| 131 | |
| 132 preedit_cursor_ = cursor; | |
| 133 preedit_text_.reset(new ibus::IBusText()); | |
| 134 preedit_text_->set_text(text); | |
| 135 | |
| 136 // TODO: Add support for displaying selected text in the composition string. | |
| 137 for (std::vector<SegmentInfo>::const_iterator segment = segments.begin(); | |
| 138 segment != segments.end(); ++segment) { | |
| 139 ibus::IBusText::UnderlineAttribute underline; | |
| 140 | |
| 141 switch (segment->style) { | |
| 142 case SEGMENT_STYLE_UNDERLINE: | |
| 143 underline.type = ibus::IBusText::IBUS_TEXT_UNDERLINE_SINGLE; | |
| 144 break; | |
| 145 case SEGMENT_STYLE_DOUBLE_UNDERLINE: | |
| 146 underline.type = ibus::IBusText::IBUS_TEXT_UNDERLINE_DOUBLE; | |
| 147 break; | |
| 148 default: | |
| 149 continue; | |
| 150 } | |
| 151 | |
| 152 underline.start_index = segment->start; | |
| 153 underline.end_index = segment->end; | |
| 154 preedit_text_->mutable_underline_attributes()->push_back(underline); | |
| 155 } | |
| 156 | |
| 157 // TODO(nona): Makes focus out mode configuable, if necessary. | |
| 158 GetCurrentService()->UpdatePreedit( | |
| 159 *preedit_text_.get(), | |
| 160 preedit_cursor_, | |
| 161 true, | |
| 162 chromeos::IBusEngineService::IBUS_ENGINE_PREEEDIT_FOCUS_OUT_MODE_COMMIT); | |
| 163 return true; | |
| 164 } | |
| 165 | |
| 166 bool InputMethodEngineIBus::ClearComposition(int context_id, | |
| 167 std::string* error) { | |
| 168 if (!active_) { | |
| 169 *error = kErrorNotActive; | |
| 170 return false; | |
| 171 } | |
| 172 if (context_id != context_id_ || context_id_ == -1) { | |
| 173 *error = kErrorWrongContext; | |
| 174 return false; | |
| 175 } | |
| 176 | |
| 177 preedit_cursor_ = 0; | |
| 178 preedit_text_.reset(new ibus::IBusText()); | |
| 179 GetCurrentService()->UpdatePreedit( | |
| 180 *preedit_text_.get(), | |
| 181 0, | |
| 182 true, | |
| 183 chromeos::IBusEngineService::IBUS_ENGINE_PREEEDIT_FOCUS_OUT_MODE_COMMIT); | |
| 184 return true; | |
| 185 } | |
| 186 | |
| 187 bool InputMethodEngineIBus::CommitText(int context_id, const char* text, | |
| 188 std::string* error) { | |
| 189 if (!active_) { | |
| 190 // TODO: Commit the text anyways. | |
| 191 *error = kErrorNotActive; | |
| 192 return false; | |
| 193 } | |
| 194 if (context_id != context_id_ || context_id_ == -1) { | |
| 195 *error = kErrorWrongContext; | |
| 196 return false; | |
| 197 } | |
| 198 | |
| 199 GetCurrentService()->CommitText(text); | |
| 200 return true; | |
| 201 } | |
| 202 | |
| 203 bool InputMethodEngineIBus::SetCandidateWindowVisible(bool visible, | |
| 204 std::string* error) { | |
| 205 if (!active_) { | |
| 206 *error = kErrorNotActive; | |
| 207 return false; | |
| 208 } | |
| 209 | |
| 210 table_visible_ = visible; | |
| 211 GetCurrentService()->UpdateLookupTable(*table_.get(), table_visible_); | |
| 212 return true; | |
| 213 } | |
| 214 | |
| 215 void InputMethodEngineIBus::SetCandidateWindowCursorVisible(bool visible) { | |
| 216 if (!active_) | |
| 217 return; | |
| 218 table_->set_is_cursor_visible(visible); | |
| 219 GetCurrentService()->UpdateLookupTable(*table_.get(), table_visible_); | |
| 220 } | |
| 221 | |
| 222 void InputMethodEngineIBus::SetCandidateWindowVertical(bool vertical) { | |
| 223 if (!active_) | |
| 224 return; | |
| 225 table_->set_orientation( | |
| 226 vertical ? ibus::IBusLookupTable::IBUS_LOOKUP_TABLE_ORIENTATION_VERTICAL : | |
| 227 ibus::IBusLookupTable::IBUS_LOOKUP_TABLE_ORIENTATION_HORIZONTAL); | |
| 228 GetCurrentService()->UpdateLookupTable(*table_.get(), table_visible_); | |
| 229 } | |
| 230 | |
| 231 void InputMethodEngineIBus::SetCandidateWindowPageSize(int size) { | |
| 232 if (!active_) | |
| 233 return; | |
| 234 table_->set_page_size(size); | |
| 235 GetCurrentService()->UpdateLookupTable(*table_.get(), table_visible_); | |
| 236 } | |
| 237 | |
| 238 void InputMethodEngineIBus::SetCandidateWindowAuxText(const char* text) { | |
| 239 if (!active_) | |
| 240 return; | |
| 241 aux_text_->set_text(text); | |
| 242 GetCurrentService()->UpdateAuxiliaryText(*aux_text_.get(), aux_text_visible_); | |
| 243 } | |
| 244 | |
| 245 void InputMethodEngineIBus::SetCandidateWindowAuxTextVisible(bool visible) { | |
| 246 if (!active_) | |
| 247 return; | |
| 248 aux_text_visible_ = visible; | |
| 249 GetCurrentService()->UpdateAuxiliaryText(*aux_text_.get(), aux_text_visible_); | |
| 250 } | |
| 251 | |
| 252 bool InputMethodEngineIBus::SetCandidates( | |
| 253 int context_id, | |
| 254 const std::vector<Candidate>& candidates, | |
| 255 std::string* error) { | |
| 256 if (!active_) { | |
| 257 *error = kErrorNotActive; | |
| 258 return false; | |
| 259 } | |
| 260 if (context_id != context_id_ || context_id_ == -1) { | |
| 261 *error = kErrorWrongContext; | |
| 262 return false; | |
| 263 } | |
| 264 | |
| 265 // TODO: Nested candidates | |
| 266 candidate_ids_.clear(); | |
| 267 candidate_indexes_.clear(); | |
| 268 table_->mutable_candidates()->clear(); | |
| 269 for (std::vector<Candidate>::const_iterator ix = candidates.begin(); | |
| 270 ix != candidates.end(); ++ix) { | |
| 271 ibus::IBusLookupTable::Entry entry; | |
| 272 // TODO(nona): support annotation(crbug.com/140186). | |
| 273 entry.value = ix->value + " " + ix->annotation; | |
| 274 entry.label = ix->label; | |
| 275 | |
| 276 // Store a mapping from the user defined ID to the candidate index. | |
| 277 candidate_indexes_[ix->id] = candidate_ids_.size(); | |
| 278 candidate_ids_.push_back(ix->id); | |
| 279 | |
| 280 table_->mutable_candidates()->push_back(entry); | |
| 281 } | |
| 282 GetCurrentService()->UpdateLookupTable(*table_.get(), table_visible_); | |
| 283 return true; | |
| 284 } | |
| 285 | |
| 286 bool InputMethodEngineIBus::SetCursorPosition(int context_id, int candidate_id, | |
| 287 std::string* error) { | |
| 288 if (!active_) { | |
| 289 *error = kErrorNotActive; | |
| 290 return false; | |
| 291 } | |
| 292 if (context_id != context_id_ || context_id_ == -1) { | |
| 293 *error = kErrorWrongContext; | |
| 294 return false; | |
| 295 } | |
| 296 | |
| 297 std::map<int, int>::const_iterator position = | |
| 298 candidate_indexes_.find(candidate_id); | |
| 299 if (position == candidate_indexes_.end()) { | |
| 300 *error = kCandidateNotFound; | |
| 301 return false; | |
| 302 } | |
| 303 | |
| 304 table_->set_cursor_position(position->second); | |
| 305 GetCurrentService()->UpdateLookupTable(*table_.get(), table_visible_); | |
| 306 return true; | |
| 307 } | |
| 308 | |
| 309 bool InputMethodEngineIBus::SetMenuItems(const std::vector<MenuItem>& items) { | |
| 310 if (!active_) | |
| 311 return false; | |
| 312 | |
| 313 ibus::IBusPropertyList properties; | |
| 314 for (std::vector<MenuItem>::const_iterator item = items.begin(); | |
| 315 item != items.end(); ++item) { | |
| 316 ibus::IBusProperty* property = new ibus::IBusProperty(); | |
| 317 if (!MenuItemToProperty(*item, property)) { | |
| 318 delete property; | |
| 319 DVLOG(1) << "Bad menu item"; | |
| 320 return false; | |
| 321 } | |
| 322 properties.push_back(property); | |
| 323 } | |
| 324 GetCurrentService()->RegisterProperties(properties); | |
| 325 return true; | |
| 326 } | |
| 327 | |
| 328 bool InputMethodEngineIBus::UpdateMenuItems( | |
| 329 const std::vector<MenuItem>& items) { | |
| 330 if (!active_) | |
| 331 return false; | |
| 332 | |
| 333 ibus::IBusPropertyList properties; | |
| 334 for (std::vector<MenuItem>::const_iterator item = items.begin(); | |
| 335 item != items.end(); ++item) { | |
| 336 ibus::IBusProperty* property = new ibus::IBusProperty(); | |
| 337 if (!MenuItemToProperty(*item, property)) { | |
| 338 delete property; | |
| 339 DVLOG(1) << "Bad menu item"; | |
| 340 return false; | |
| 341 } | |
| 342 properties.push_back(property); | |
| 343 } | |
| 344 GetCurrentService()->RegisterProperties(properties); | |
| 345 return true; | |
| 346 } | |
| 347 | |
| 348 bool InputMethodEngineIBus::IsActive() const { | |
| 349 return active_; | |
| 350 } | |
| 351 | |
| 352 void InputMethodEngineIBus::KeyEventDone(input_method::KeyEventHandle* key_data, | |
| 353 bool handled) { | |
| 354 KeyEventDoneCallback* callback = | |
| 355 reinterpret_cast<KeyEventDoneCallback*>(key_data); | |
| 356 callback->Run(handled); | |
| 357 delete callback; | |
| 358 } | |
| 359 | |
| 360 void InputMethodEngineIBus::FocusIn() { | |
| 361 focused_ = true; | |
| 362 if (!active_) | |
| 363 return; | |
| 364 context_id_ = next_context_id_; | |
| 365 ++next_context_id_; | |
| 366 | |
| 367 InputContext context; | |
| 368 context.id = context_id_; | |
| 369 // TODO: Other types | |
| 370 context.type = "text"; | |
| 371 | |
| 372 observer_->OnFocus(context); | |
| 373 } | |
| 374 | |
| 375 void InputMethodEngineIBus::FocusOut() { | |
| 376 focused_ = false; | |
| 377 if (!active_) | |
| 378 return; | |
| 379 int context_id = context_id_; | |
| 380 context_id_ = -1; | |
| 381 observer_->OnBlur(context_id); | |
| 382 } | |
| 383 | |
| 384 void InputMethodEngineIBus::Enable() { | |
| 385 active_ = true; | |
| 386 observer_->OnActivate(engine_id_); | |
| 387 FocusIn(); | |
| 388 } | |
| 389 | |
| 390 void InputMethodEngineIBus::Disable() { | |
| 391 active_ = false; | |
| 392 observer_->OnDeactivated(engine_id_); | |
| 393 } | |
| 394 | |
| 395 void InputMethodEngineIBus::PropertyActivate( | |
| 396 const std::string& property_name, | |
| 397 IBusPropertyState property_state) { | |
| 398 observer_->OnMenuItemActivated(engine_id_, property_name); | |
| 399 } | |
| 400 | |
| 401 void InputMethodEngineIBus::PropertyShow( | |
| 402 const std::string& property_name) { | |
| 403 } | |
| 404 | |
| 405 void InputMethodEngineIBus::PropertyHide( | |
| 406 const std::string& property_name) { | |
| 407 } | |
| 408 | |
| 409 void InputMethodEngineIBus::SetCapability( | |
| 410 IBusCapability capability) { | |
| 411 } | |
| 412 | |
| 413 void InputMethodEngineIBus::Reset() { | |
| 414 } | |
| 415 | |
| 416 void InputMethodEngineIBus::ProcessKeyEvent( | |
| 417 uint32 keysym, | |
| 418 uint32 keycode, | |
| 419 uint32 state, | |
| 420 const KeyEventDoneCallback& callback) { | |
| 421 | |
| 422 KeyEventDoneCallback *handler = new KeyEventDoneCallback(); | |
| 423 *handler = callback; | |
| 424 | |
| 425 KeyboardEvent event; | |
| 426 event.type = !(state & kIBusKeyReleaseMask) ? "keydown" : "keyup"; | |
| 427 event.key = input_method::GetIBusKey(keysym); | |
| 428 event.alt_key = state & kIBusAltKeyMask; | |
| 429 event.ctrl_key = state & kIBusCtrlKeyMask; | |
| 430 event.shift_key = state & kIBusShiftKeyMask; | |
| 431 observer_->OnKeyEvent( | |
| 432 engine_id_, | |
| 433 event, | |
| 434 reinterpret_cast<input_method::KeyEventHandle*>(handler)); | |
| 435 } | |
| 436 | |
| 437 void InputMethodEngineIBus::CandidateClicked( | |
| 438 uint32 index, | |
| 439 IBusMouseButton button, | |
| 440 uint32 state) { | |
| 441 if (index > candidate_ids_.size()) { | |
| 442 return; | |
| 443 } | |
| 444 | |
| 445 MouseButtonEvent pressed_button; | |
| 446 switch (button) { | |
| 447 case IBusEngineHandlerInterface::IBUS_MOUSE_BUTTON_LEFT: | |
| 448 pressed_button = MOUSE_BUTTON_LEFT; | |
| 449 break; | |
| 450 case IBusEngineHandlerInterface::IBUS_MOUSE_BUTTON_MIDDLE: | |
| 451 pressed_button = MOUSE_BUTTON_MIDDLE; | |
| 452 break; | |
| 453 case IBusEngineHandlerInterface::IBUS_MOUSE_BUTTON_RIGHT: | |
| 454 pressed_button = MOUSE_BUTTON_RIGHT; | |
| 455 break; | |
| 456 default: | |
| 457 DVLOG(1) << "Unknown button: " << button; | |
| 458 pressed_button = MOUSE_BUTTON_LEFT; | |
| 459 break; | |
| 460 } | |
| 461 | |
| 462 observer_->OnCandidateClicked( | |
| 463 engine_id_, candidate_ids_.at(index), pressed_button); | |
| 464 } | |
| 465 | |
| 466 void InputMethodEngineIBus::SetSurroundingText( | |
| 467 const std::string& text, | |
| 468 uint32 cursor_pos, | |
| 469 uint32 anchor_pos) { | |
| 470 } | |
| 471 | |
| 472 IBusEngineService* InputMethodEngineIBus::GetCurrentService() { | |
| 473 return DBusThreadManager::Get()->GetIBusEngineService(object_path_); | |
| 474 } | |
| 475 | |
| 476 bool InputMethodEngineIBus::MenuItemToProperty( | |
| 477 const MenuItem& item, | |
| 478 ibus::IBusProperty* property) { | |
| 479 property->set_key(item.id); | |
| 480 | |
| 481 if (item.modified & MENU_ITEM_MODIFIED_LABEL) { | |
| 482 property->set_label(item.label); | |
| 483 } | |
| 484 if (item.modified & MENU_ITEM_MODIFIED_VISIBLE) { | |
| 485 property->set_visible(item.visible); | |
| 486 } | |
| 487 if (item.modified & MENU_ITEM_MODIFIED_CHECKED) { | |
| 488 property->set_checked(item.checked); | |
| 489 } | |
| 490 if (item.modified & MENU_ITEM_MODIFIED_ENABLED) { | |
| 491 // TODO(nona): implement sensitive entry(crbug.com/140192). | |
| 492 } | |
| 493 if (item.modified & MENU_ITEM_MODIFIED_STYLE) { | |
| 494 ibus::IBusProperty::IBusPropertyType type = | |
| 495 ibus::IBusProperty::IBUS_PROPERTY_TYPE_NORMAL; | |
| 496 if (!item.children.empty()) { | |
| 497 type = ibus::IBusProperty::IBUS_PROPERTY_TYPE_MENU; | |
| 498 } else { | |
| 499 switch (item.style) { | |
| 500 case MENU_ITEM_STYLE_NONE: | |
| 501 type = ibus::IBusProperty::IBUS_PROPERTY_TYPE_NORMAL; | |
| 502 break; | |
| 503 case MENU_ITEM_STYLE_CHECK: | |
| 504 type = ibus::IBusProperty::IBUS_PROPERTY_TYPE_TOGGLE; | |
| 505 break; | |
| 506 case MENU_ITEM_STYLE_RADIO: | |
| 507 type = ibus::IBusProperty::IBUS_PROPERTY_TYPE_RADIO; | |
| 508 break; | |
| 509 case MENU_ITEM_STYLE_SEPARATOR: | |
| 510 type = ibus::IBusProperty::IBUS_PROPERTY_TYPE_SEPARATOR; | |
| 511 break; | |
| 512 } | |
| 513 } | |
| 514 property->set_type(type); | |
| 515 } | |
| 516 | |
| 517 for (std::vector<MenuItem>::const_iterator child = item.children.begin(); | |
| 518 child != item.children.end(); ++child) { | |
| 519 ibus::IBusProperty* new_property = new ibus::IBusProperty(); | |
| 520 if (!MenuItemToProperty(*child, new_property)) { | |
| 521 delete new_property; | |
| 522 DVLOG(1) << "Bad menu item child"; | |
| 523 return false; | |
| 524 } | |
| 525 property->mutable_sub_properties()->push_back(new_property); | |
| 526 } | |
| 527 | |
| 528 return true; | |
| 529 } | |
| 530 | |
| 531 void InputMethodEngineIBus::OnConnected() { | |
| 532 RegisterComponent(); | |
| 533 } | |
| 534 | |
| 535 void InputMethodEngineIBus::OnDisconnected() { | |
| 536 } | |
| 537 | |
| 538 bool InputMethodEngineIBus::IsConnected() { | |
| 539 return DBusThreadManager::Get()->GetIBusClient() != NULL; | |
| 540 } | |
| 541 | |
| 542 void InputMethodEngineIBus::RegisterComponent() { | |
| 543 chromeos::IBusClient* client = | |
| 544 chromeos::DBusThreadManager::Get()->GetIBusClient(); | |
| 545 client->RegisterComponent( | |
| 546 *component_.get(), | |
| 547 base::Bind(&InputMethodEngineIBus::OnComponentRegistered, | |
| 548 weak_ptr_factory_.GetWeakPtr()), | |
| 549 base::Bind(&InputMethodEngineIBus::OnComponentRegistrationFailed, | |
| 550 weak_ptr_factory_.GetWeakPtr())); | |
| 551 } | |
| 552 | |
| 553 void InputMethodEngineIBus::OnComponentRegistered() { | |
| 554 DBusThreadManager::Get()->GetIBusEngineFactoryService()-> | |
| 555 SetCreateEngineHandler(ibus_id_, | |
| 556 base::Bind( | |
| 557 &InputMethodEngineIBus::CreateEngineHandler, | |
| 558 weak_ptr_factory_.GetWeakPtr())); | |
| 559 } | |
| 560 | |
| 561 void InputMethodEngineIBus::OnComponentRegistrationFailed() { | |
| 562 // TODO(nona): Implement error handling. | |
|
Zachary Kuznia
2012/08/07 06:41:04
Log an error here.
Seigo Nonaka
2012/08/07 17:39:21
Done.
| |
| 563 } | |
| 564 | |
| 565 void InputMethodEngineIBus::CreateEngineHandler( | |
| 566 const IBusEngineFactoryService::CreateEngineResponseSender& sender) { | |
| 567 DBusThreadManager::Get()->RemoveIBusEngineService(object_path_); | |
| 568 | |
| 569 const std::string kObjectPathPrefix = "/org/freedesktop/IBus/Engine/"; | |
|
Zachary Kuznia
2012/08/07 06:41:04
Put this constant at the top of the file.
Seigo Nonaka
2012/08/07 17:39:21
Done.
| |
| 570 current_object_path_++; | |
| 571 object_path_ = dbus::ObjectPath(kObjectPathPrefix + | |
| 572 base::IntToString(current_object_path_)); | |
| 573 GetCurrentService()->Initialize(this); | |
| 574 sender.Run(object_path_); | |
| 575 } | |
| 576 | |
| 577 } // namespace chromeos | |
| OLD | NEW |