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 |