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 <msctf.h> | 5 #include <msctf.h> |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
(...skipping 21 matching lines...) Expand all Loading... |
32 class TSFBridgeDelegate : public TSFBridge { | 32 class TSFBridgeDelegate : public TSFBridge { |
33 public: | 33 public: |
34 TSFBridgeDelegate(); | 34 TSFBridgeDelegate(); |
35 virtual ~TSFBridgeDelegate(); | 35 virtual ~TSFBridgeDelegate(); |
36 | 36 |
37 bool Initialize(); | 37 bool Initialize(); |
38 | 38 |
39 // TsfBridge: | 39 // TsfBridge: |
40 virtual void Shutdown() OVERRIDE; | 40 virtual void Shutdown() OVERRIDE; |
41 virtual void OnTextInputTypeChanged(TextInputClient* client) OVERRIDE; | 41 virtual void OnTextInputTypeChanged(TextInputClient* client) OVERRIDE; |
42 virtual void OnTextLayoutChanged() OVERRIDE; | |
43 virtual bool CancelComposition() OVERRIDE; | 42 virtual bool CancelComposition() OVERRIDE; |
44 virtual void SetFocusedClient(HWND focused_window, | 43 virtual void SetFocusedClient(HWND focused_window, |
45 TextInputClient* client) OVERRIDE; | 44 TextInputClient* client) OVERRIDE; |
46 virtual void RemoveFocusedClient(TextInputClient* client) OVERRIDE; | 45 virtual void RemoveFocusedClient(TextInputClient* client) OVERRIDE; |
47 virtual base::win::ScopedComPtr<ITfThreadMgr> GetThreadManager() OVERRIDE; | 46 virtual base::win::ScopedComPtr<ITfThreadMgr> GetThreadManager() OVERRIDE; |
48 virtual TextInputClient* GetFocusedTextInputClient() const OVERRIDE; | 47 virtual TextInputClient* GetFocusedTextInputClient() const OVERRIDE; |
49 | 48 |
50 private: | 49 private: |
51 friend struct DefaultSingletonTraits<TSFBridgeDelegate>; | 50 friend struct DefaultSingletonTraits<TSFBridgeDelegate>; |
52 | 51 |
(...skipping 15 matching lines...) Expand all Loading... |
68 ITfDocumentMgr** document_manager, | 67 ITfDocumentMgr** document_manager, |
69 ITfContext** context, | 68 ITfContext** context, |
70 DWORD* source_cookie); | 69 DWORD* source_cookie); |
71 | 70 |
72 // Returns true if |document_manager| is the focused document manager. | 71 // Returns true if |document_manager| is the focused document manager. |
73 bool IsFocused(ITfDocumentMgr* document_manager); | 72 bool IsFocused(ITfDocumentMgr* document_manager); |
74 | 73 |
75 // Returns true if already initialized. | 74 // Returns true if already initialized. |
76 bool IsInitialized(); | 75 bool IsInitialized(); |
77 | 76 |
| 77 // Returns an instance of ITfDocumentMgr that is associated with the |
| 78 // current TextInputType of |client_|. |
| 79 base::win::ScopedComPtr<ITfDocumentMgr> GetAssociatedDocumentManager(); |
| 80 |
| 81 // An ITfThreadMgr object to be used in focus and document management. |
| 82 base::win::ScopedComPtr<ITfThreadMgr> thread_manager_; |
| 83 |
78 // A triple of document manager, text store and binding cookie between | 84 // A triple of document manager, text store and binding cookie between |
79 // a context owned by the document manager and the text store. This is a | 85 // a context owned by the document manager and the text store. This is a |
80 // minimum working set of an editable document in TSF. | 86 // minimum working set of an editable document in TSF. |
81 struct TSFDocument { | 87 struct TSFDocument { |
82 public: | 88 public: |
83 TSFDocument() : cookie(TF_INVALID_COOKIE) {} | 89 TSFDocument() : cookie(TF_INVALID_COOKIE) {} |
84 TSFDocument(const TSFDocument& src) | 90 TSFDocument(const TSFDocument& src) |
85 : document_manager(src.document_manager), | 91 : document_manager(src.document_manager), |
86 cookie(src.cookie) {} | 92 cookie(src.cookie) {} |
87 base::win::ScopedComPtr<ITfDocumentMgr> document_manager; | 93 base::win::ScopedComPtr<ITfDocumentMgr> document_manager; |
88 scoped_refptr<TSFTextStore> text_store; | 94 scoped_refptr<TSFTextStore> text_store; |
89 DWORD cookie; | 95 DWORD cookie; |
90 }; | 96 }; |
91 | 97 |
92 // Returns a pointer to TSFDocument that is associated with the current | |
93 // TextInputType of |client_|. | |
94 TSFDocument* GetAssociatedDocument(); | |
95 | |
96 // An ITfThreadMgr object to be used in focus and document management. | |
97 base::win::ScopedComPtr<ITfThreadMgr> thread_manager_; | |
98 | |
99 // A map from TextInputType to an editable document for TSF. We use multiple | 98 // A map from TextInputType to an editable document for TSF. We use multiple |
100 // TSF documents that have different InputScopes and TSF attributes based on | 99 // TSF documents that have different InputScopes and TSF attributes based on |
101 // the TextInputType associated with the target document. For a TextInputType | 100 // the TextInputType associated with the target document. For a TextInputType |
102 // that is not converted by this map, a default document, e.g. the document | 101 // that is not coverted by this map, a default document, e.g. the document |
103 // for TEXT_INPUT_TYPE_TEXT, should be used. | 102 // for TEXT_INPUT_TYPE_TEXT, should be used. |
104 // Note that some IMEs don't change their state unless the document focus is | 103 // Note that some IMEs don't change their state unless the document focus is |
105 // changed. This is why we use multiple documents instead of changing TSF | 104 // changed. This is why we use multiple documents instead of changing TSF |
106 // metadata of a single document on the fly. | 105 // metadata of a single document on the fly. |
107 typedef std::map<TextInputType, TSFDocument> TSFDocumentMap; | 106 typedef std::map<TextInputType, TSFDocument> TSFDocumentMap; |
108 TSFDocumentMap tsf_document_map_; | 107 TSFDocumentMap tsf_document_map_; |
109 | 108 |
110 // An identifier of TSF client. | 109 // An identifier of TSF client. |
111 TfClientId client_id_; | 110 TfClientId client_id_; |
112 | 111 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 } | 191 } |
193 | 192 |
194 void TSFBridgeDelegate::OnTextInputTypeChanged(TextInputClient* client) { | 193 void TSFBridgeDelegate::OnTextInputTypeChanged(TextInputClient* client) { |
195 DCHECK_EQ(base::MessageLoop::TYPE_UI, base::MessageLoop::current()->type()); | 194 DCHECK_EQ(base::MessageLoop::TYPE_UI, base::MessageLoop::current()->type()); |
196 DCHECK(IsInitialized()); | 195 DCHECK(IsInitialized()); |
197 | 196 |
198 if (client != client_) { | 197 if (client != client_) { |
199 // Called from not focusing client. Do nothing. | 198 // Called from not focusing client. Do nothing. |
200 return; | 199 return; |
201 } | 200 } |
202 TSFDocument* document = GetAssociatedDocument(); | |
203 if (!document) | |
204 return; | |
205 thread_manager_->SetFocus(document->document_manager.get()); | |
206 OnTextLayoutChanged(); | |
207 } | |
208 | 201 |
209 void TSFBridgeDelegate::OnTextLayoutChanged() { | 202 thread_manager_->SetFocus(GetAssociatedDocumentManager().get()); |
210 TSFDocument* document = GetAssociatedDocument(); | |
211 if (!document) | |
212 return; | |
213 if (!document->text_store) | |
214 return; | |
215 document->text_store->SendOnLayoutChange(); | |
216 } | 203 } |
217 | 204 |
218 bool TSFBridgeDelegate::CancelComposition() { | 205 bool TSFBridgeDelegate::CancelComposition() { |
219 DCHECK_EQ(base::MessageLoop::TYPE_UI, base::MessageLoop::current()->type()); | 206 DCHECK_EQ(base::MessageLoop::TYPE_UI, base::MessageLoop::current()->type()); |
220 DCHECK(IsInitialized()); | 207 DCHECK(IsInitialized()); |
221 | 208 |
222 base::win::ScopedComPtr<ITfDocumentMgr> focused_document_manager; | 209 base::win::ScopedComPtr<ITfDocumentMgr> focused_document_manager; |
223 for (TSFDocumentMap::iterator it = tsf_document_map_.begin(); | 210 for (TSFDocumentMap::iterator it = tsf_document_map_.begin(); |
224 it != tsf_document_map_.end(); ++it) { | 211 it != tsf_document_map_.end(); ++it) { |
225 if (IsFocused(it->second.document_manager.get())) { | 212 if (IsFocused(it->second.document_manager.get())) { |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 base::win::ScopedComPtr<ITfDocumentMgr> focused_document_manager; | 410 base::win::ScopedComPtr<ITfDocumentMgr> focused_document_manager; |
424 if (FAILED(thread_manager_->GetFocus(focused_document_manager.Receive()))) | 411 if (FAILED(thread_manager_->GetFocus(focused_document_manager.Receive()))) |
425 return false; | 412 return false; |
426 return focused_document_manager.IsSameObject(document_manager); | 413 return focused_document_manager.IsSameObject(document_manager); |
427 } | 414 } |
428 | 415 |
429 bool TSFBridgeDelegate::IsInitialized() { | 416 bool TSFBridgeDelegate::IsInitialized() { |
430 return client_id_ != TF_CLIENTID_NULL; | 417 return client_id_ != TF_CLIENTID_NULL; |
431 } | 418 } |
432 | 419 |
433 TSFBridgeDelegate::TSFDocument* TSFBridgeDelegate::GetAssociatedDocument() { | 420 base::win::ScopedComPtr<ITfDocumentMgr> |
434 if (!client_) | 421 TSFBridgeDelegate::GetAssociatedDocumentManager() { |
435 return NULL; | 422 TSFDocumentMap::const_iterator it = |
436 TSFDocumentMap::iterator it = | |
437 tsf_document_map_.find(client_->GetTextInputType()); | 423 tsf_document_map_.find(client_->GetTextInputType()); |
438 if (it == tsf_document_map_.end()) | 424 if (it == tsf_document_map_.end()) |
439 return &tsf_document_map_[TEXT_INPUT_TYPE_TEXT]; | 425 return tsf_document_map_[TEXT_INPUT_TYPE_TEXT].document_manager; |
440 return &it->second; | 426 return it->second.document_manager; |
441 } | 427 } |
442 | 428 |
443 } // namespace | 429 } // namespace |
444 | 430 |
445 | 431 |
446 // TsfBridge ----------------------------------------------------------------- | 432 // TsfBridge ----------------------------------------------------------------- |
447 | 433 |
448 TSFBridge::TSFBridge() { | 434 TSFBridge::TSFBridge() { |
449 } | 435 } |
450 | 436 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
489 return delegate; | 475 return delegate; |
490 } | 476 } |
491 | 477 |
492 // static | 478 // static |
493 void TSFBridge::Finalize(void* data) { | 479 void TSFBridge::Finalize(void* data) { |
494 TSFBridgeDelegate* delegate = static_cast<TSFBridgeDelegate*>(data); | 480 TSFBridgeDelegate* delegate = static_cast<TSFBridgeDelegate*>(data); |
495 delete delegate; | 481 delete delegate; |
496 } | 482 } |
497 | 483 |
498 } // namespace ui | 484 } // namespace ui |
OLD | NEW |