| 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 |