| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 "win8/metro_driver/ime/text_service.h" | 5 #include "win8/metro_driver/ime/text_service.h" |
| 6 | 6 |
| 7 #include <msctf.h> | 7 #include <msctf.h> |
| 8 #include <stddef.h> |
| 9 #include <stdint.h> |
| 8 | 10 |
| 9 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/macros.h" |
| 10 #include "base/win/scoped_variant.h" | 13 #include "base/win/scoped_variant.h" |
| 11 #include "ui/metro_viewer/ime_types.h" | 14 #include "ui/metro_viewer/ime_types.h" |
| 12 #include "win8/metro_driver/ime/text_service_delegate.h" | 15 #include "win8/metro_driver/ime/text_service_delegate.h" |
| 13 #include "win8/metro_driver/ime/text_store.h" | 16 #include "win8/metro_driver/ime/text_store.h" |
| 14 #include "win8/metro_driver/ime/text_store_delegate.h" | 17 #include "win8/metro_driver/ime/text_store_delegate.h" |
| 15 | 18 |
| 16 // Architecture overview of input method support on Ash mode: | 19 // Architecture overview of input method support on Ash mode: |
| 17 // | 20 // |
| 18 // Overview: | 21 // Overview: |
| 19 // On Ash mode, the system keyboard focus is owned by the metro_driver process | 22 // On Ash mode, the system keyboard focus is owned by the metro_driver process |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 | 149 |
| 147 base::win::ScopedComPtr<ITfCompartment> empty_context; | 150 base::win::ScopedComPtr<ITfCompartment> empty_context; |
| 148 hr = compartment_mgr->GetCompartment(GUID_COMPARTMENT_EMPTYCONTEXT, | 151 hr = compartment_mgr->GetCompartment(GUID_COMPARTMENT_EMPTYCONTEXT, |
| 149 empty_context.Receive()); | 152 empty_context.Receive()); |
| 150 if (FAILED(hr)) { | 153 if (FAILED(hr)) { |
| 151 LOG(ERROR) << "ITfCompartment::GetCompartment failed. hr = " << hr; | 154 LOG(ERROR) << "ITfCompartment::GetCompartment failed. hr = " << hr; |
| 152 return false; | 155 return false; |
| 153 } | 156 } |
| 154 | 157 |
| 155 base::win::ScopedVariant empty_context_variant; | 158 base::win::ScopedVariant empty_context_variant; |
| 156 empty_context_variant.Set(static_cast<int32>(1)); | 159 empty_context_variant.Set(static_cast<int32_t>(1)); |
| 157 hr = empty_context->SetValue(client_id, empty_context_variant.ptr()); | 160 hr = empty_context->SetValue(client_id, empty_context_variant.ptr()); |
| 158 if (FAILED(hr)) { | 161 if (FAILED(hr)) { |
| 159 LOG(ERROR) << "ITfCompartment::SetValue failed. hr = " << hr; | 162 LOG(ERROR) << "ITfCompartment::SetValue failed. hr = " << hr; |
| 160 return false; | 163 return false; |
| 161 } | 164 } |
| 162 | 165 |
| 163 return true; | 166 return true; |
| 164 } | 167 } |
| 165 | 168 |
| 166 bool IsPasswordField(const std::vector<InputScope>& input_scopes) { | 169 bool IsPasswordField(const std::vector<InputScope>& input_scopes) { |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 if (!current_document_) { | 339 if (!current_document_) { |
| 337 VLOG(0) << "|current_document_| is NULL due to the previous error."; | 340 VLOG(0) << "|current_document_| is NULL due to the previous error."; |
| 338 return; | 341 return; |
| 339 } | 342 } |
| 340 scoped_refptr<TextStore> text_store = current_document_->text_store(); | 343 scoped_refptr<TextStore> text_store = current_document_->text_store(); |
| 341 if (!text_store.get()) | 344 if (!text_store.get()) |
| 342 return; | 345 return; |
| 343 text_store->CancelComposition(); | 346 text_store->CancelComposition(); |
| 344 } | 347 } |
| 345 | 348 |
| 346 void OnDocumentChanged( | 349 void OnDocumentChanged(const std::vector<int32_t>& input_scopes, |
| 347 const std::vector<int32>& input_scopes, | 350 const std::vector<metro_viewer::CharacterBounds>& |
| 348 const std::vector<metro_viewer::CharacterBounds>& character_bounds) | 351 character_bounds) override { |
| 349 override { | |
| 350 bool document_type_changed = input_scopes_ != input_scopes; | 352 bool document_type_changed = input_scopes_ != input_scopes; |
| 351 input_scopes_ = input_scopes; | 353 input_scopes_ = input_scopes; |
| 352 composition_character_bounds_ = character_bounds; | 354 composition_character_bounds_ = character_bounds; |
| 353 if (document_type_changed) | 355 if (document_type_changed) |
| 354 OnDocumentTypeChanged(input_scopes); | 356 OnDocumentTypeChanged(input_scopes); |
| 355 } | 357 } |
| 356 | 358 |
| 357 void OnWindowActivated() override { | 359 void OnWindowActivated() override { |
| 358 if (!current_document_) { | 360 if (!current_document_) { |
| 359 VLOG(0) << "|current_document_| is NULL due to the previous error."; | 361 VLOG(0) << "|current_document_| is NULL due to the previous error."; |
| 360 return; | 362 return; |
| 361 } | 363 } |
| 362 ITfDocumentMgr* document_manager = current_document_->document_manager(); | 364 ITfDocumentMgr* document_manager = current_document_->document_manager(); |
| 363 if (!document_manager) { | 365 if (!document_manager) { |
| 364 VLOG(0) << "|document_manager| is NULL due to the previous error."; | 366 VLOG(0) << "|document_manager| is NULL due to the previous error."; |
| 365 return; | 367 return; |
| 366 } | 368 } |
| 367 HRESULT hr = thread_manager_->SetFocus(document_manager); | 369 HRESULT hr = thread_manager_->SetFocus(document_manager); |
| 368 if (FAILED(hr)) { | 370 if (FAILED(hr)) { |
| 369 LOG(ERROR) << "ITfThreadMgr::SetFocus failed. hr = " << hr; | 371 LOG(ERROR) << "ITfThreadMgr::SetFocus failed. hr = " << hr; |
| 370 return; | 372 return; |
| 371 } | 373 } |
| 372 } | 374 } |
| 373 | 375 |
| 374 void OnCompositionChanged( | 376 void OnCompositionChanged( |
| 375 const base::string16& text, | 377 const base::string16& text, |
| 376 int32 selection_start, | 378 int32_t selection_start, |
| 377 int32 selection_end, | 379 int32_t selection_end, |
| 378 const std::vector<metro_viewer::UnderlineInfo>& underlines) override { | 380 const std::vector<metro_viewer::UnderlineInfo>& underlines) override { |
| 379 if (!delegate_) | 381 if (!delegate_) |
| 380 return; | 382 return; |
| 381 delegate_->OnCompositionChanged(text, | 383 delegate_->OnCompositionChanged(text, |
| 382 selection_start, | 384 selection_start, |
| 383 selection_end, | 385 selection_end, |
| 384 underlines); | 386 underlines); |
| 385 } | 387 } |
| 386 | 388 |
| 387 void OnTextCommitted(const base::string16& text) override { | 389 void OnTextCommitted(const base::string16& text) override { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 403 ClientToScreen(window_handle_, &right_bottom); | 405 ClientToScreen(window_handle_, &right_bottom); |
| 404 const RECT rect = { | 406 const RECT rect = { |
| 405 left_top.x, | 407 left_top.x, |
| 406 left_top.y, | 408 left_top.y, |
| 407 right_bottom.x, | 409 right_bottom.x, |
| 408 right_bottom.y, | 410 right_bottom.y, |
| 409 }; | 411 }; |
| 410 return rect; | 412 return rect; |
| 411 } | 413 } |
| 412 | 414 |
| 413 bool GetCompositionCharacterBounds(uint32 index, RECT* rect) override { | 415 bool GetCompositionCharacterBounds(uint32_t index, RECT* rect) override { |
| 414 if (index >= composition_character_bounds_.size()) { | 416 if (index >= composition_character_bounds_.size()) { |
| 415 return false; | 417 return false; |
| 416 } | 418 } |
| 417 const metro_viewer::CharacterBounds& bounds = | 419 const metro_viewer::CharacterBounds& bounds = |
| 418 composition_character_bounds_[index]; | 420 composition_character_bounds_[index]; |
| 419 POINT left_top = { bounds.left, bounds.top }; | 421 POINT left_top = { bounds.left, bounds.top }; |
| 420 POINT right_bottom = { bounds.right, bounds.bottom }; | 422 POINT right_bottom = { bounds.right, bounds.bottom }; |
| 421 ClientToScreen(window_handle_, &left_top); | 423 ClientToScreen(window_handle_, &left_top); |
| 422 ClientToScreen(window_handle_, &right_bottom); | 424 ClientToScreen(window_handle_, &right_bottom); |
| 423 SetRect(rect, left_top.x, left_top.y, right_bottom.x, right_bottom.y); | 425 SetRect(rect, left_top.x, left_top.y, right_bottom.x, right_bottom.y); |
| 424 return true; | 426 return true; |
| 425 } | 427 } |
| 426 | 428 |
| 427 void OnDocumentTypeChanged(const std::vector<int32>& input_scopes) { | 429 void OnDocumentTypeChanged(const std::vector<int32_t>& input_scopes) { |
| 428 std::vector<InputScope> native_input_scopes(input_scopes.size()); | 430 std::vector<InputScope> native_input_scopes(input_scopes.size()); |
| 429 for (size_t i = 0; i < input_scopes.size(); ++i) | 431 for (size_t i = 0; i < input_scopes.size(); ++i) |
| 430 native_input_scopes[i] = static_cast<InputScope>(input_scopes[i]); | 432 native_input_scopes[i] = static_cast<InputScope>(input_scopes[i]); |
| 431 scoped_ptr<DocumentBinding> new_document = | 433 scoped_ptr<DocumentBinding> new_document = |
| 432 DocumentBinding::Create(thread_manager_.get(), | 434 DocumentBinding::Create(thread_manager_.get(), |
| 433 client_id_, | 435 client_id_, |
| 434 native_input_scopes, | 436 native_input_scopes, |
| 435 window_handle_, | 437 window_handle_, |
| 436 this); | 438 this); |
| 437 LOG_IF(ERROR, !new_document) << "Failed to create a new document."; | 439 LOG_IF(ERROR, !new_document) << "Failed to create a new document."; |
| 438 current_document_.swap(new_document); | 440 current_document_.swap(new_document); |
| 439 OnWindowActivated(); | 441 OnWindowActivated(); |
| 440 } | 442 } |
| 441 | 443 |
| 442 TfClientId client_id_; | 444 TfClientId client_id_; |
| 443 HWND window_handle_; | 445 HWND window_handle_; |
| 444 TextServiceDelegate* delegate_; | 446 TextServiceDelegate* delegate_; |
| 445 scoped_ptr<DocumentBinding> current_document_; | 447 scoped_ptr<DocumentBinding> current_document_; |
| 446 base::win::ScopedComPtr<ITfThreadMgr> thread_manager_; | 448 base::win::ScopedComPtr<ITfThreadMgr> thread_manager_; |
| 447 | 449 |
| 448 // A vector of InputScope enumeration, which represents the document type of | 450 // A vector of InputScope enumeration, which represents the document type of |
| 449 // the focused text field. Note that in our IPC message protocol, an empty | 451 // the focused text field. Note that in our IPC message protocol, an empty |
| 450 // |input_scopes_| has special meaning that IMEs must be disabled on this | 452 // |input_scopes_| has special meaning that IMEs must be disabled on this |
| 451 // document. | 453 // document. |
| 452 std::vector<int32> input_scopes_; | 454 std::vector<int32_t> input_scopes_; |
| 453 // Character bounds of the composition. When there is no composition but this | 455 // Character bounds of the composition. When there is no composition but this |
| 454 // vector is not empty, the first element contains the caret bounds. | 456 // vector is not empty, the first element contains the caret bounds. |
| 455 std::vector<metro_viewer::CharacterBounds> composition_character_bounds_; | 457 std::vector<metro_viewer::CharacterBounds> composition_character_bounds_; |
| 456 | 458 |
| 457 DISALLOW_COPY_AND_ASSIGN(TextServiceImpl); | 459 DISALLOW_COPY_AND_ASSIGN(TextServiceImpl); |
| 458 }; | 460 }; |
| 459 | 461 |
| 460 } // namespace | 462 } // namespace |
| 461 | 463 |
| 462 scoped_ptr<TextService> | 464 scoped_ptr<TextService> |
| (...skipping 16 matching lines...) Expand all Loading... |
| 479 if (!InitializeSentenceMode(thread_manager.get(), client_id)) { | 481 if (!InitializeSentenceMode(thread_manager.get(), client_id)) { |
| 480 LOG(ERROR) << "InitializeSentenceMode failed."; | 482 LOG(ERROR) << "InitializeSentenceMode failed."; |
| 481 thread_manager->Deactivate(); | 483 thread_manager->Deactivate(); |
| 482 return scoped_ptr<TextService>(); | 484 return scoped_ptr<TextService>(); |
| 483 } | 485 } |
| 484 return scoped_ptr<TextService>(new TextServiceImpl( | 486 return scoped_ptr<TextService>(new TextServiceImpl( |
| 485 thread_manager.get(), client_id, window_handle, delegate)); | 487 thread_manager.get(), client_id, window_handle, delegate)); |
| 486 } | 488 } |
| 487 | 489 |
| 488 } // namespace metro_driver | 490 } // namespace metro_driver |
| OLD | NEW |