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