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_store.h" | 5 #include "win8/metro_driver/ime/text_store.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/win/scoped_variant.h" | 9 #include "base/win/scoped_variant.h" |
10 #include "ui/base/win/atl_module.h" | 10 #include "ui/base/win/atl_module.h" |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 return scoped_refptr<TextStore>(); | 52 return scoped_refptr<TextStore>(); |
53 } | 53 } |
54 base::win::ScopedComPtr<ITfDisplayAttributeMgr> display_attribute_manager; | 54 base::win::ScopedComPtr<ITfDisplayAttributeMgr> display_attribute_manager; |
55 hr = display_attribute_manager.CreateInstance(CLSID_TF_DisplayAttributeMgr); | 55 hr = display_attribute_manager.CreateInstance(CLSID_TF_DisplayAttributeMgr); |
56 if (FAILED(hr)) { | 56 if (FAILED(hr)) { |
57 LOG(ERROR) << "Failed to initialize DisplayAttributeMgr. hr = " << hr; | 57 LOG(ERROR) << "Failed to initialize DisplayAttributeMgr. hr = " << hr; |
58 return scoped_refptr<TextStore>(); | 58 return scoped_refptr<TextStore>(); |
59 } | 59 } |
60 base::win::ScopedComPtr<ITfInputScope> input_scope = | 60 base::win::ScopedComPtr<ITfInputScope> input_scope = |
61 CreteInputScope(input_scopes); | 61 CreteInputScope(input_scopes); |
62 if (!input_scope) { | 62 if (!input_scope.get()) { |
63 LOG(ERROR) << "Failed to initialize InputScope."; | 63 LOG(ERROR) << "Failed to initialize InputScope."; |
64 return scoped_refptr<TextStore>(); | 64 return scoped_refptr<TextStore>(); |
65 } | 65 } |
66 | 66 |
67 ui::win::CreateATLModuleIfNeeded(); | 67 ui::win::CreateATLModuleIfNeeded(); |
68 CComObject<TextStore>* object = NULL; | 68 CComObject<TextStore>* object = NULL; |
69 hr = CComObject<TextStore>::CreateInstance(&object); | 69 hr = CComObject<TextStore>::CreateInstance(&object); |
70 if (FAILED(hr)) { | 70 if (FAILED(hr)) { |
71 LOG(ERROR) << "CComObject<TextStore>::CreateInstance failed. hr = " | 71 LOG(ERROR) << "CComObject<TextStore>::CreateInstance failed. hr = " |
72 << hr; | 72 << hr; |
73 return scoped_refptr<TextStore>(); | 73 return scoped_refptr<TextStore>(); |
74 } | 74 } |
75 object->Initialize(window_handle, | 75 object->Initialize(window_handle, category_manager.get(), |
76 category_manager, | 76 display_attribute_manager.get(), input_scope.get(), |
77 display_attribute_manager, | |
78 input_scope, | |
79 delegate); | 77 delegate); |
80 return scoped_refptr<TextStore>(object); | 78 return scoped_refptr<TextStore>(object); |
81 } | 79 } |
82 | 80 |
83 void TextStore::Initialize(HWND window_handle, | 81 void TextStore::Initialize(HWND window_handle, |
84 ITfCategoryMgr* category_manager, | 82 ITfCategoryMgr* category_manager, |
85 ITfDisplayAttributeMgr* display_attribute_manager, | 83 ITfDisplayAttributeMgr* display_attribute_manager, |
86 ITfInputScope* input_scope, | 84 ITfInputScope* input_scope, |
87 TextStoreDelegate* delegate) { | 85 TextStoreDelegate* delegate) { |
88 window_handle_ = window_handle; | 86 window_handle_ = window_handle; |
89 category_manager_ = category_manager; | 87 category_manager_ = category_manager; |
90 display_attribute_manager_ = display_attribute_manager; | 88 display_attribute_manager_ = display_attribute_manager; |
91 input_scope_ = input_scope; | 89 input_scope_ = input_scope; |
92 delegate_ = delegate; | 90 delegate_ = delegate; |
93 } | 91 } |
94 | 92 |
95 | 93 |
96 STDMETHODIMP TextStore::AdviseSink(REFIID iid, | 94 STDMETHODIMP TextStore::AdviseSink(REFIID iid, |
97 IUnknown* unknown, | 95 IUnknown* unknown, |
98 DWORD mask) { | 96 DWORD mask) { |
99 if (!IsEqualGUID(iid, IID_ITextStoreACPSink)) | 97 if (!IsEqualGUID(iid, IID_ITextStoreACPSink)) |
100 return E_INVALIDARG; | 98 return E_INVALIDARG; |
101 if (text_store_acp_sink_) { | 99 if (text_store_acp_sink_.get()) { |
102 if (text_store_acp_sink_.IsSameObject(unknown)) { | 100 if (text_store_acp_sink_.IsSameObject(unknown)) { |
103 text_store_acp_sink_mask_ = mask; | 101 text_store_acp_sink_mask_ = mask; |
104 return S_OK; | 102 return S_OK; |
105 } else { | 103 } else { |
106 return CONNECT_E_ADVISELIMIT; | 104 return CONNECT_E_ADVISELIMIT; |
107 } | 105 } |
108 } | 106 } |
109 if (FAILED(text_store_acp_sink_.QueryFrom(unknown))) | 107 if (FAILED(text_store_acp_sink_.QueryFrom(unknown))) |
110 return E_UNEXPECTED; | 108 return E_UNEXPECTED; |
111 text_store_acp_sink_mask_ = mask; | 109 text_store_acp_sink_mask_ = mask; |
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
574 | 572 |
575 return S_OK; | 573 return S_OK; |
576 } | 574 } |
577 | 575 |
578 STDMETHODIMP TextStore::RequestSupportedAttrs( | 576 STDMETHODIMP TextStore::RequestSupportedAttrs( |
579 DWORD /* flags */, // Seems that we should ignore this. | 577 DWORD /* flags */, // Seems that we should ignore this. |
580 ULONG attribute_buffer_size, | 578 ULONG attribute_buffer_size, |
581 const TS_ATTRID* attribute_buffer) { | 579 const TS_ATTRID* attribute_buffer) { |
582 if (!attribute_buffer) | 580 if (!attribute_buffer) |
583 return E_INVALIDARG; | 581 return E_INVALIDARG; |
584 if (!input_scope_) | 582 if (!input_scope_.get()) |
585 return E_FAIL; | 583 return E_FAIL; |
586 // We support only input scope attribute. | 584 // We support only input scope attribute. |
587 for (size_t i = 0; i < attribute_buffer_size; ++i) { | 585 for (size_t i = 0; i < attribute_buffer_size; ++i) { |
588 if (IsEqualGUID(GUID_PROP_INPUTSCOPE, attribute_buffer[i])) | 586 if (IsEqualGUID(GUID_PROP_INPUTSCOPE, attribute_buffer[i])) |
589 return S_OK; | 587 return S_OK; |
590 } | 588 } |
591 return E_FAIL; | 589 return E_FAIL; |
592 } | 590 } |
593 | 591 |
594 STDMETHODIMP TextStore::RetrieveRequestedAttrs( | 592 STDMETHODIMP TextStore::RetrieveRequestedAttrs( |
595 ULONG attribute_buffer_size, | 593 ULONG attribute_buffer_size, |
596 TS_ATTRVAL* attribute_buffer, | 594 TS_ATTRVAL* attribute_buffer, |
597 ULONG* attribute_buffer_copied) { | 595 ULONG* attribute_buffer_copied) { |
598 if (!attribute_buffer_copied) | 596 if (!attribute_buffer_copied) |
599 return E_INVALIDARG; | 597 return E_INVALIDARG; |
600 *attribute_buffer_copied = 0; | 598 *attribute_buffer_copied = 0; |
601 if (!attribute_buffer) | 599 if (!attribute_buffer) |
602 return E_INVALIDARG; | 600 return E_INVALIDARG; |
603 if (!input_scope_) | 601 if (!input_scope_.get()) |
604 return E_UNEXPECTED; | 602 return E_UNEXPECTED; |
605 // We support only input scope attribute. | 603 // We support only input scope attribute. |
606 *attribute_buffer_copied = 0; | 604 *attribute_buffer_copied = 0; |
607 if (attribute_buffer_size == 0) | 605 if (attribute_buffer_size == 0) |
608 return S_OK; | 606 return S_OK; |
609 | 607 |
610 attribute_buffer[0].dwOverlapId = 0; | 608 attribute_buffer[0].dwOverlapId = 0; |
611 attribute_buffer[0].idAttr = GUID_PROP_INPUTSCOPE; | 609 attribute_buffer[0].idAttr = GUID_PROP_INPUTSCOPE; |
612 attribute_buffer[0].varValue.vt = VT_UNKNOWN; | 610 attribute_buffer[0].varValue.vt = VT_UNKNOWN; |
613 attribute_buffer[0].varValue.punkVal = input_scope_.get(); | 611 attribute_buffer[0].varValue.punkVal = input_scope_.get(); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
744 *committed_size = 0; | 742 *committed_size = 0; |
745 undelines->clear(); | 743 undelines->clear(); |
746 base::win::ScopedComPtr<ITfRange> start_to_end_range; | 744 base::win::ScopedComPtr<ITfRange> start_to_end_range; |
747 base::win::ScopedComPtr<ITfRange> end_range; | 745 base::win::ScopedComPtr<ITfRange> end_range; |
748 if (FAILED(context->GetStart(read_only_edit_cookie, | 746 if (FAILED(context->GetStart(read_only_edit_cookie, |
749 start_to_end_range.Receive()))) { | 747 start_to_end_range.Receive()))) { |
750 return false; | 748 return false; |
751 } | 749 } |
752 if (FAILED(context->GetEnd(read_only_edit_cookie, end_range.Receive()))) | 750 if (FAILED(context->GetEnd(read_only_edit_cookie, end_range.Receive()))) |
753 return false; | 751 return false; |
754 if (FAILED(start_to_end_range->ShiftEndToRange(read_only_edit_cookie, | 752 if (FAILED(start_to_end_range->ShiftEndToRange( |
755 end_range, TF_ANCHOR_END))) { | 753 read_only_edit_cookie, end_range.get(), TF_ANCHOR_END))) { |
756 return false; | 754 return false; |
757 } | 755 } |
758 | 756 |
759 base::win::ScopedComPtr<IEnumTfRanges> ranges; | 757 base::win::ScopedComPtr<IEnumTfRanges> ranges; |
760 if (FAILED(track_property->EnumRanges(read_only_edit_cookie, ranges.Receive(), | 758 if (FAILED(track_property->EnumRanges(read_only_edit_cookie, ranges.Receive(), |
761 start_to_end_range))) { | 759 start_to_end_range.get()))) { |
762 return false; | 760 return false; |
763 } | 761 } |
764 | 762 |
765 while (true) { | 763 while (true) { |
766 base::win::ScopedComPtr<ITfRange> range; | 764 base::win::ScopedComPtr<ITfRange> range; |
767 if (ranges->Next(1, range.Receive(), NULL) != S_OK) | 765 if (ranges->Next(1, range.Receive(), NULL) != S_OK) |
768 return true; | 766 return true; |
769 base::win::ScopedVariant value; | 767 base::win::ScopedVariant value; |
770 base::win::ScopedComPtr<IEnumTfPropertyValue> enum_prop_value; | 768 base::win::ScopedComPtr<IEnumTfPropertyValue> enum_prop_value; |
771 if (FAILED(track_property->GetValue(read_only_edit_cookie, range, | 769 if (FAILED(track_property->GetValue(read_only_edit_cookie, range.get(), |
772 value.Receive()))) { | 770 value.Receive()))) { |
773 return false; | 771 return false; |
774 } | 772 } |
775 if (FAILED(enum_prop_value.QueryFrom(value.AsInput()->punkVal))) | 773 if (FAILED(enum_prop_value.QueryFrom(value.AsInput()->punkVal))) |
776 return false; | 774 return false; |
777 | 775 |
778 TF_PROPERTYVAL property_value; | 776 TF_PROPERTYVAL property_value; |
779 bool is_composition = false; | 777 bool is_composition = false; |
780 metro_viewer::UnderlineInfo underline; | 778 metro_viewer::UnderlineInfo underline; |
781 while (enum_prop_value->Next(1, &property_value, NULL) == S_OK) { | 779 while (enum_prop_value->Next(1, &property_value, NULL) == S_OK) { |
782 if (IsEqualGUID(property_value.guidId, GUID_PROP_COMPOSING)) { | 780 if (IsEqualGUID(property_value.guidId, GUID_PROP_COMPOSING)) { |
783 is_composition = (property_value.varValue.lVal == TRUE); | 781 is_composition = (property_value.varValue.lVal == TRUE); |
784 } else if (IsEqualGUID(property_value.guidId, GUID_PROP_ATTRIBUTE)) { | 782 } else if (IsEqualGUID(property_value.guidId, GUID_PROP_ATTRIBUTE)) { |
785 TfGuidAtom guid_atom = | 783 TfGuidAtom guid_atom = |
786 static_cast<TfGuidAtom>(property_value.varValue.lVal); | 784 static_cast<TfGuidAtom>(property_value.varValue.lVal); |
787 TF_DISPLAYATTRIBUTE display_attribute; | 785 TF_DISPLAYATTRIBUTE display_attribute; |
788 if (GetDisplayAttribute(guid_atom, &display_attribute)) | 786 if (GetDisplayAttribute(guid_atom, &display_attribute)) |
789 underline.thick = !!display_attribute.fBoldLine; | 787 underline.thick = !!display_attribute.fBoldLine; |
790 } | 788 } |
791 VariantClear(&property_value.varValue); | 789 VariantClear(&property_value.varValue); |
792 } | 790 } |
793 | 791 |
794 base::win::ScopedComPtr<ITfRangeACP> range_acp; | 792 base::win::ScopedComPtr<ITfRangeACP> range_acp; |
795 range_acp.QueryFrom(range); | 793 range_acp.QueryFrom(range.get()); |
796 LONG start_pos, length; | 794 LONG start_pos, length; |
797 range_acp->GetExtent(&start_pos, &length); | 795 range_acp->GetExtent(&start_pos, &length); |
798 if (is_composition) { | 796 if (is_composition) { |
799 underline.start_offset = start_pos; | 797 underline.start_offset = start_pos; |
800 underline.end_offset = start_pos + length; | 798 underline.end_offset = start_pos + length; |
801 undelines->push_back(underline); | 799 undelines->push_back(underline); |
802 } else if (*committed_size < static_cast<size_t>(start_pos + length)) { | 800 } else if (*committed_size < static_cast<size_t>(start_pos + length)) { |
803 *committed_size = start_pos + length; | 801 *committed_size = start_pos + length; |
804 } | 802 } |
805 } | 803 } |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
872 TS_TEXTCHANGE textChange = {}; | 870 TS_TEXTCHANGE textChange = {}; |
873 textChange.acpStart = 0; | 871 textChange.acpStart = 0; |
874 textChange.acpOldEnd = previous_buffer_size; | 872 textChange.acpOldEnd = previous_buffer_size; |
875 textChange.acpNewEnd = 0; | 873 textChange.acpNewEnd = 0; |
876 text_store_acp_sink_->OnTextChange(0, &textChange); | 874 text_store_acp_sink_->OnTextChange(0, &textChange); |
877 } | 875 } |
878 return true; | 876 return true; |
879 } | 877 } |
880 | 878 |
881 void TextStore::SendOnLayoutChange() { | 879 void TextStore::SendOnLayoutChange() { |
882 if (text_store_acp_sink_ && (text_store_acp_sink_mask_ & TS_AS_LAYOUT_CHANGE)) | 880 if (text_store_acp_sink_.get() && |
| 881 (text_store_acp_sink_mask_ & TS_AS_LAYOUT_CHANGE)) { |
883 text_store_acp_sink_->OnLayoutChange(TS_LC_CHANGE, 0); | 882 text_store_acp_sink_->OnLayoutChange(TS_LC_CHANGE, 0); |
| 883 } |
884 } | 884 } |
885 | 885 |
886 bool TextStore::HasReadLock() const { | 886 bool TextStore::HasReadLock() const { |
887 return (current_lock_type_ & TS_LF_READ) == TS_LF_READ; | 887 return (current_lock_type_ & TS_LF_READ) == TS_LF_READ; |
888 } | 888 } |
889 | 889 |
890 bool TextStore::HasReadWriteLock() const { | 890 bool TextStore::HasReadWriteLock() const { |
891 return (current_lock_type_ & TS_LF_READWRITE) == TS_LF_READWRITE; | 891 return (current_lock_type_ & TS_LF_READWRITE) == TS_LF_READWRITE; |
892 } | 892 } |
893 | 893 |
894 } // namespace metro_driver | 894 } // namespace metro_driver |
OLD | NEW |