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 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/win/scoped_variant.h" | 10 #include "base/win/scoped_variant.h" |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 // about what will be involved in this multi-phase construction. See also | 85 // about what will be involved in this multi-phase construction. See also |
86 // text_store.cc and input_scope.cc for more underlying details. | 86 // text_store.cc and input_scope.cc for more underlying details. |
87 | 87 |
88 namespace metro_driver { | 88 namespace metro_driver { |
89 namespace { | 89 namespace { |
90 | 90 |
91 // Japanese IME expects the default value of this compartment is | 91 // Japanese IME expects the default value of this compartment is |
92 // TF_SENTENCEMODE_PHRASEPREDICT to emulate IMM32 behavior. This value is | 92 // TF_SENTENCEMODE_PHRASEPREDICT to emulate IMM32 behavior. This value is |
93 // managed per thread, thus setting this value at once is sufficient. This | 93 // managed per thread, thus setting this value at once is sufficient. This |
94 // value never affects non-Japanese IMEs. | 94 // value never affects non-Japanese IMEs. |
95 bool InitializeSentenceMode(ITfThreadMgr2* thread_manager, | 95 bool InitializeSentenceMode(ITfThreadMgr* thread_manager, |
96 TfClientId client_id) { | 96 TfClientId client_id) { |
97 base::win::ScopedComPtr<ITfCompartmentMgr> thread_compartment_manager; | 97 base::win::ScopedComPtr<ITfCompartmentMgr> thread_compartment_manager; |
98 HRESULT hr = thread_compartment_manager.QueryFrom(thread_manager); | 98 HRESULT hr = thread_compartment_manager.QueryFrom(thread_manager); |
99 if (FAILED(hr)) { | 99 if (FAILED(hr)) { |
100 LOG(ERROR) << "QueryFrom failed. hr = " << hr; | 100 LOG(ERROR) << "QueryFrom failed. hr = " << hr; |
101 return false; | 101 return false; |
102 } | 102 } |
103 base::win::ScopedComPtr<ITfCompartment> sentence_compartment; | 103 base::win::ScopedComPtr<ITfCompartment> sentence_compartment; |
104 hr = thread_compartment_manager->GetCompartment( | 104 hr = thread_compartment_manager->GetCompartment( |
105 GUID_COMPARTMENT_KEYBOARD_INPUTMODE_SENTENCE, | 105 GUID_COMPARTMENT_KEYBOARD_INPUTMODE_SENTENCE, |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 // TSF runtime and TextStore is unregistered when this object is destroyed. | 217 // TSF runtime and TextStore is unregistered when this object is destroyed. |
218 class DocumentBinding { | 218 class DocumentBinding { |
219 public: | 219 public: |
220 ~DocumentBinding() { | 220 ~DocumentBinding() { |
221 if (!document_manager_) | 221 if (!document_manager_) |
222 return; | 222 return; |
223 document_manager_->Pop(TF_POPF_ALL); | 223 document_manager_->Pop(TF_POPF_ALL); |
224 } | 224 } |
225 | 225 |
226 static scoped_ptr<DocumentBinding> Create( | 226 static scoped_ptr<DocumentBinding> Create( |
227 ITfThreadMgr2* thread_manager, | 227 ITfThreadMgr* thread_manager, |
228 TfClientId client_id, | 228 TfClientId client_id, |
229 const std::vector<InputScope>& input_scopes, | 229 const std::vector<InputScope>& input_scopes, |
230 HWND window_handle, | 230 HWND window_handle, |
231 TextStoreDelegate* delegate) { | 231 TextStoreDelegate* delegate) { |
232 base::win::ScopedComPtr<ITfDocumentMgr> document_manager; | 232 base::win::ScopedComPtr<ITfDocumentMgr> document_manager; |
233 HRESULT hr = thread_manager->CreateDocumentMgr(document_manager.Receive()); | 233 HRESULT hr = thread_manager->CreateDocumentMgr(document_manager.Receive()); |
234 if (FAILED(hr)) { | 234 if (FAILED(hr)) { |
235 LOG(ERROR) << "ITfThreadMgr2::CreateDocumentMgr failed. hr = " << hr; | 235 LOG(ERROR) << "ITfThreadMgr::CreateDocumentMgr failed. hr = " << hr; |
236 return scoped_ptr<DocumentBinding>(); | 236 return scoped_ptr<DocumentBinding>(); |
237 } | 237 } |
238 | 238 |
239 // Note: In our IPC protocol, an empty |input_scopes| is used to indicate | 239 // Note: In our IPC protocol, an empty |input_scopes| is used to indicate |
240 // that an IME must be disabled in this context. In such case, we need not | 240 // that an IME must be disabled in this context. In such case, we need not |
241 // instantiate TextStore. | 241 // instantiate TextStore. |
242 const bool use_null_text_store = input_scopes.empty(); | 242 const bool use_null_text_store = input_scopes.empty(); |
243 | 243 |
244 scoped_refptr<TextStore> text_store; | 244 scoped_refptr<TextStore> text_store; |
245 if (!use_null_text_store) { | 245 if (!use_null_text_store) { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 scoped_refptr<TextStore> text_store_; | 309 scoped_refptr<TextStore> text_store_; |
310 base::win::ScopedComPtr<ITfDocumentMgr> document_manager_; | 310 base::win::ScopedComPtr<ITfDocumentMgr> document_manager_; |
311 scoped_ptr<EventSink> text_edit_sink_; | 311 scoped_ptr<EventSink> text_edit_sink_; |
312 | 312 |
313 DISALLOW_COPY_AND_ASSIGN(DocumentBinding); | 313 DISALLOW_COPY_AND_ASSIGN(DocumentBinding); |
314 }; | 314 }; |
315 | 315 |
316 class TextServiceImpl : public TextService, | 316 class TextServiceImpl : public TextService, |
317 public TextStoreDelegate { | 317 public TextStoreDelegate { |
318 public: | 318 public: |
319 TextServiceImpl(ITfThreadMgr2* thread_manager, | 319 TextServiceImpl(ITfThreadMgr* thread_manager, |
320 TfClientId client_id, | 320 TfClientId client_id, |
321 HWND window_handle, | 321 HWND window_handle, |
322 TextServiceDelegate* delegate) | 322 TextServiceDelegate* delegate) |
323 : client_id_(client_id), | 323 : client_id_(client_id), |
324 window_handle_(window_handle), | 324 window_handle_(window_handle), |
325 delegate_(delegate), | 325 delegate_(delegate), |
326 thread_manager_(thread_manager) { | 326 thread_manager_(thread_manager) { |
327 DCHECK_NE(TF_CLIENTID_NULL, client_id); | 327 DCHECK_NE(TF_CLIENTID_NULL, client_id); |
328 DCHECK(window_handle != NULL); | 328 DCHECK(window_handle != NULL); |
329 DCHECK(thread_manager_); | 329 DCHECK(thread_manager_); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 VLOG(0) << "|current_document_| is NULL due to the previous error."; | 361 VLOG(0) << "|current_document_| is NULL due to the previous error."; |
362 return; | 362 return; |
363 } | 363 } |
364 ITfDocumentMgr* document_manager = current_document_->document_manager(); | 364 ITfDocumentMgr* document_manager = current_document_->document_manager(); |
365 if (!document_manager) { | 365 if (!document_manager) { |
366 VLOG(0) << "|document_manager| is NULL due to the previous error."; | 366 VLOG(0) << "|document_manager| is NULL due to the previous error."; |
367 return; | 367 return; |
368 } | 368 } |
369 HRESULT hr = thread_manager_->SetFocus(document_manager); | 369 HRESULT hr = thread_manager_->SetFocus(document_manager); |
370 if (FAILED(hr)) { | 370 if (FAILED(hr)) { |
371 LOG(ERROR) << "ITfThreadMgr2::SetFocus failed. hr = " << hr; | 371 LOG(ERROR) << "ITfThreadMgr::SetFocus failed. hr = " << hr; |
372 return; | 372 return; |
373 } | 373 } |
374 } | 374 } |
375 | 375 |
376 virtual void OnCompositionChanged( | 376 virtual void OnCompositionChanged( |
377 const base::string16& text, | 377 const base::string16& text, |
378 int32 selection_start, | 378 int32 selection_start, |
379 int32 selection_end, | 379 int32 selection_end, |
380 const std::vector<metro_viewer::UnderlineInfo>& underlines) override { | 380 const std::vector<metro_viewer::UnderlineInfo>& underlines) override { |
381 if (!delegate_) | 381 if (!delegate_) |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 this); | 439 this); |
440 LOG_IF(ERROR, !new_document) << "Failed to create a new document."; | 440 LOG_IF(ERROR, !new_document) << "Failed to create a new document."; |
441 current_document_.swap(new_document); | 441 current_document_.swap(new_document); |
442 OnWindowActivated(); | 442 OnWindowActivated(); |
443 } | 443 } |
444 | 444 |
445 TfClientId client_id_; | 445 TfClientId client_id_; |
446 HWND window_handle_; | 446 HWND window_handle_; |
447 TextServiceDelegate* delegate_; | 447 TextServiceDelegate* delegate_; |
448 scoped_ptr<DocumentBinding> current_document_; | 448 scoped_ptr<DocumentBinding> current_document_; |
449 base::win::ScopedComPtr<ITfThreadMgr2> thread_manager_; | 449 base::win::ScopedComPtr<ITfThreadMgr> thread_manager_; |
450 | 450 |
451 // A vector of InputScope enumeration, which represents the document type of | 451 // A vector of InputScope enumeration, which represents the document type of |
452 // the focused text field. Note that in our IPC message protocol, an empty | 452 // the focused text field. Note that in our IPC message protocol, an empty |
453 // |input_scopes_| has special meaning that IMEs must be disabled on this | 453 // |input_scopes_| has special meaning that IMEs must be disabled on this |
454 // document. | 454 // document. |
455 std::vector<int32> input_scopes_; | 455 std::vector<int32> input_scopes_; |
456 // Character bounds of the composition. When there is no composition but this | 456 // Character bounds of the composition. When there is no composition but this |
457 // vector is not empty, the first element contains the caret bounds. | 457 // vector is not empty, the first element contains the caret bounds. |
458 std::vector<metro_viewer::CharacterBounds> composition_character_bounds_; | 458 std::vector<metro_viewer::CharacterBounds> composition_character_bounds_; |
459 | 459 |
460 DISALLOW_COPY_AND_ASSIGN(TextServiceImpl); | 460 DISALLOW_COPY_AND_ASSIGN(TextServiceImpl); |
461 }; | 461 }; |
462 | 462 |
463 } // namespace | 463 } // namespace |
464 | 464 |
465 scoped_ptr<TextService> | 465 scoped_ptr<TextService> |
466 CreateTextService(TextServiceDelegate* delegate, HWND window_handle) { | 466 CreateTextService(TextServiceDelegate* delegate, HWND window_handle) { |
467 if (!delegate) | 467 if (!delegate) |
468 return scoped_ptr<TextService>(); | 468 return scoped_ptr<TextService>(); |
469 base::win::ScopedComPtr<ITfThreadMgr2> thread_manager; | 469 base::win::ScopedComPtr<ITfThreadMgr> thread_manager; |
470 HRESULT hr = thread_manager.CreateInstance(CLSID_TF_ThreadMgr); | 470 HRESULT hr = thread_manager.CreateInstance(CLSID_TF_ThreadMgr); |
471 if (FAILED(hr)) { | 471 if (FAILED(hr)) { |
472 LOG(ERROR) << "Failed to create instance of CLSID_TF_ThreadMgr. hr = " | 472 LOG(ERROR) << "Failed to create instance of CLSID_TF_ThreadMgr. hr = " |
473 << hr; | 473 << hr; |
474 return scoped_ptr<TextService>(); | 474 return scoped_ptr<TextService>(); |
475 } | 475 } |
476 TfClientId client_id = TF_CLIENTID_NULL; | 476 TfClientId client_id = TF_CLIENTID_NULL; |
477 hr = thread_manager->ActivateEx(&client_id, 0); | 477 hr = thread_manager->Activate(&client_id); |
478 if (FAILED(hr)) { | 478 if (FAILED(hr)) { |
479 LOG(ERROR) << "ITfThreadMgr2::ActivateEx failed. hr = " << hr; | 479 LOG(ERROR) << "ITfThreadMgr::Activate failed. hr = " << hr; |
480 return scoped_ptr<TextService>(); | 480 return scoped_ptr<TextService>(); |
481 } | 481 } |
482 if (!InitializeSentenceMode(thread_manager, client_id)) { | 482 if (!InitializeSentenceMode(thread_manager, client_id)) { |
483 LOG(ERROR) << "InitializeSentenceMode failed."; | 483 LOG(ERROR) << "InitializeSentenceMode failed."; |
484 thread_manager->Deactivate(); | 484 thread_manager->Deactivate(); |
485 return scoped_ptr<TextService>(); | 485 return scoped_ptr<TextService>(); |
486 } | 486 } |
487 return scoped_ptr<TextService>(new TextServiceImpl(thread_manager, | 487 return scoped_ptr<TextService>(new TextServiceImpl(thread_manager, |
488 client_id, | 488 client_id, |
489 window_handle, | 489 window_handle, |
490 delegate)); | 490 delegate)); |
491 } | 491 } |
492 | 492 |
493 } // namespace metro_driver | 493 } // namespace metro_driver |
OLD | NEW |