| 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" |
| 11 #include "win8/metro_driver/ime/input_scope.h" | 11 #include "win8/metro_driver/ime/input_scope.h" |
| 12 #include "win8/metro_driver/ime/text_store_delegate.h" | 12 #include "win8/metro_driver/ime/text_store_delegate.h" |
| 13 | 13 |
| 14 namespace metro_driver { | 14 namespace metro_driver { |
| 15 namespace { | 15 namespace { |
| 16 | 16 |
| 17 // We support only one view. | 17 // We support only one view. |
| 18 const TsViewCookie kViewCookie = 1; | 18 const TsViewCookie kViewCookie = 1; |
| 19 | 19 |
| 20 } // namespace | 20 } // namespace |
| 21 | 21 |
| 22 TSFTextStore::TSFTextStore() | 22 TextStore::TextStore() |
| 23 : text_store_acp_sink_mask_(0), | 23 : text_store_acp_sink_mask_(0), |
| 24 window_handle_(NULL), | 24 window_handle_(NULL), |
| 25 delegate_(NULL), | 25 delegate_(NULL), |
| 26 committed_size_(0), | 26 committed_size_(0), |
| 27 selection_start_(0), | 27 selection_start_(0), |
| 28 selection_end_(0), | 28 selection_end_(0), |
| 29 edit_flag_(false), | 29 edit_flag_(false), |
| 30 current_lock_type_(0), | 30 current_lock_type_(0), |
| 31 category_manager_(NULL), | 31 category_manager_(NULL), |
| 32 display_attribute_manager_(NULL), | 32 display_attribute_manager_(NULL), |
| 33 input_scope_(NULL) { | 33 input_scope_(NULL) { |
| 34 } | 34 } |
| 35 | 35 |
| 36 TSFTextStore::~TSFTextStore() { | 36 TextStore::~TextStore() { |
| 37 } | 37 } |
| 38 | 38 |
| 39 // static | 39 // static |
| 40 scoped_refptr<TSFTextStore> TSFTextStore::Create( | 40 scoped_refptr<TextStore> TextStore::Create( |
| 41 HWND window_handle, | 41 HWND window_handle, |
| 42 const std::vector<InputScope>& input_scopes, | 42 const std::vector<InputScope>& input_scopes, |
| 43 TextStoreDelegate* delegate) { | 43 TextStoreDelegate* delegate) { |
| 44 if (!delegate) { | 44 if (!delegate) { |
| 45 LOG(ERROR) << "|delegate| must be non-NULL."; | 45 LOG(ERROR) << "|delegate| must be non-NULL."; |
| 46 return scoped_refptr<TSFTextStore>(); | 46 return scoped_refptr<TextStore>(); |
| 47 } | 47 } |
| 48 base::win::ScopedComPtr<ITfCategoryMgr> category_manager; | 48 base::win::ScopedComPtr<ITfCategoryMgr> category_manager; |
| 49 HRESULT hr = category_manager.CreateInstance(CLSID_TF_CategoryMgr); | 49 HRESULT hr = category_manager.CreateInstance(CLSID_TF_CategoryMgr); |
| 50 if (FAILED(hr)) { | 50 if (FAILED(hr)) { |
| 51 LOG(ERROR) << "Failed to initialize CategoryMgr. hr = " << hr; | 51 LOG(ERROR) << "Failed to initialize CategoryMgr. hr = " << hr; |
| 52 return scoped_refptr<TSFTextStore>(); | 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<TSFTextStore>(); | 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) { |
| 63 LOG(ERROR) << "Failed to initialize InputScope."; | 63 LOG(ERROR) << "Failed to initialize InputScope."; |
| 64 return scoped_refptr<TSFTextStore>(); | 64 return scoped_refptr<TextStore>(); |
| 65 } | 65 } |
| 66 | 66 |
| 67 ui::win::CreateATLModuleIfNeeded(); | 67 ui::win::CreateATLModuleIfNeeded(); |
| 68 CComObject<TSFTextStore>* object = NULL; | 68 CComObject<TextStore>* object = NULL; |
| 69 hr = CComObject<TSFTextStore>::CreateInstance(&object); | 69 hr = CComObject<TextStore>::CreateInstance(&object); |
| 70 if (FAILED(hr)) { | 70 if (FAILED(hr)) { |
| 71 LOG(ERROR) << "CComObject<TSFTextStore>::CreateInstance failed. hr = " | 71 LOG(ERROR) << "CComObject<TextStore>::CreateInstance failed. hr = " |
| 72 << hr; | 72 << hr; |
| 73 return scoped_refptr<TSFTextStore>(); | 73 return scoped_refptr<TextStore>(); |
| 74 } | 74 } |
| 75 object->Initialize(window_handle, | 75 object->Initialize(window_handle, |
| 76 category_manager, | 76 category_manager, |
| 77 display_attribute_manager, | 77 display_attribute_manager, |
| 78 input_scope, | 78 input_scope, |
| 79 delegate); | 79 delegate); |
| 80 return scoped_refptr<TSFTextStore>(object); | 80 return scoped_refptr<TextStore>(object); |
| 81 } | 81 } |
| 82 | 82 |
| 83 void TSFTextStore::Initialize(HWND window_handle, | 83 void TextStore::Initialize(HWND window_handle, |
| 84 ITfCategoryMgr* category_manager, | 84 ITfCategoryMgr* category_manager, |
| 85 ITfDisplayAttributeMgr* display_attribute_manager, | 85 ITfDisplayAttributeMgr* display_attribute_manager, |
| 86 ITfInputScope* input_scope, | 86 ITfInputScope* input_scope, |
| 87 TextStoreDelegate* delegate) { | 87 TextStoreDelegate* delegate) { |
| 88 window_handle_ = window_handle; | 88 window_handle_ = window_handle; |
| 89 category_manager_ = category_manager; | 89 category_manager_ = category_manager; |
| 90 display_attribute_manager_ = display_attribute_manager; | 90 display_attribute_manager_ = display_attribute_manager; |
| 91 input_scope_ = input_scope; | 91 input_scope_ = input_scope; |
| 92 delegate_ = delegate; | 92 delegate_ = delegate; |
| 93 } | 93 } |
| 94 | 94 |
| 95 | 95 |
| 96 STDMETHODIMP TSFTextStore::AdviseSink(REFIID iid, | 96 STDMETHODIMP TextStore::AdviseSink(REFIID iid, |
| 97 IUnknown* unknown, | 97 IUnknown* unknown, |
| 98 DWORD mask) { | 98 DWORD mask) { |
| 99 if (!IsEqualGUID(iid, IID_ITextStoreACPSink)) | 99 if (!IsEqualGUID(iid, IID_ITextStoreACPSink)) |
| 100 return E_INVALIDARG; | 100 return E_INVALIDARG; |
| 101 if (text_store_acp_sink_) { | 101 if (text_store_acp_sink_) { |
| 102 if (text_store_acp_sink_.IsSameObject(unknown)) { | 102 if (text_store_acp_sink_.IsSameObject(unknown)) { |
| 103 text_store_acp_sink_mask_ = mask; | 103 text_store_acp_sink_mask_ = mask; |
| 104 return S_OK; | 104 return S_OK; |
| 105 } else { | 105 } else { |
| 106 return CONNECT_E_ADVISELIMIT; | 106 return CONNECT_E_ADVISELIMIT; |
| 107 } | 107 } |
| 108 } | 108 } |
| 109 if (FAILED(text_store_acp_sink_.QueryFrom(unknown))) | 109 if (FAILED(text_store_acp_sink_.QueryFrom(unknown))) |
| 110 return E_UNEXPECTED; | 110 return E_UNEXPECTED; |
| 111 text_store_acp_sink_mask_ = mask; | 111 text_store_acp_sink_mask_ = mask; |
| 112 | 112 |
| 113 return S_OK; | 113 return S_OK; |
| 114 } | 114 } |
| 115 | 115 |
| 116 STDMETHODIMP TSFTextStore::FindNextAttrTransition( | 116 STDMETHODIMP TextStore::FindNextAttrTransition( |
| 117 LONG acp_start, | 117 LONG acp_start, |
| 118 LONG acp_halt, | 118 LONG acp_halt, |
| 119 ULONG num_filter_attributes, | 119 ULONG num_filter_attributes, |
| 120 const TS_ATTRID* filter_attributes, | 120 const TS_ATTRID* filter_attributes, |
| 121 DWORD flags, | 121 DWORD flags, |
| 122 LONG* acp_next, | 122 LONG* acp_next, |
| 123 BOOL* found, | 123 BOOL* found, |
| 124 LONG* found_offset) { | 124 LONG* found_offset) { |
| 125 if (!acp_next || !found || !found_offset) | 125 if (!acp_next || !found || !found_offset) |
| 126 return E_INVALIDARG; | 126 return E_INVALIDARG; |
| 127 // We don't support any attributes. | 127 // We don't support any attributes. |
| 128 // So we always return "not found". | 128 // So we always return "not found". |
| 129 *acp_next = 0; | 129 *acp_next = 0; |
| 130 *found = FALSE; | 130 *found = FALSE; |
| 131 *found_offset = 0; | 131 *found_offset = 0; |
| 132 return S_OK; | 132 return S_OK; |
| 133 } | 133 } |
| 134 | 134 |
| 135 STDMETHODIMP TSFTextStore::GetACPFromPoint(TsViewCookie view_cookie, | 135 STDMETHODIMP TextStore::GetACPFromPoint(TsViewCookie view_cookie, |
| 136 const POINT* point, | 136 const POINT* point, |
| 137 DWORD flags, | 137 DWORD flags, |
| 138 LONG* acp) { | 138 LONG* acp) { |
| 139 NOTIMPLEMENTED(); | 139 NOTIMPLEMENTED(); |
| 140 if (view_cookie != kViewCookie) | 140 if (view_cookie != kViewCookie) |
| 141 return E_INVALIDARG; | 141 return E_INVALIDARG; |
| 142 return E_NOTIMPL; | 142 return E_NOTIMPL; |
| 143 } | 143 } |
| 144 | 144 |
| 145 STDMETHODIMP TSFTextStore::GetActiveView(TsViewCookie* view_cookie) { | 145 STDMETHODIMP TextStore::GetActiveView(TsViewCookie* view_cookie) { |
| 146 if (!view_cookie) | 146 if (!view_cookie) |
| 147 return E_INVALIDARG; | 147 return E_INVALIDARG; |
| 148 // We support only one view. | 148 // We support only one view. |
| 149 *view_cookie = kViewCookie; | 149 *view_cookie = kViewCookie; |
| 150 return S_OK; | 150 return S_OK; |
| 151 } | 151 } |
| 152 | 152 |
| 153 STDMETHODIMP TSFTextStore::GetEmbedded(LONG acp_pos, | 153 STDMETHODIMP TextStore::GetEmbedded(LONG acp_pos, |
| 154 REFGUID service, | 154 REFGUID service, |
| 155 REFIID iid, | 155 REFIID iid, |
| 156 IUnknown** unknown) { | 156 IUnknown** unknown) { |
| 157 // We don't support any embedded objects. | 157 // We don't support any embedded objects. |
| 158 NOTIMPLEMENTED(); | 158 NOTIMPLEMENTED(); |
| 159 if (!unknown) | 159 if (!unknown) |
| 160 return E_INVALIDARG; | 160 return E_INVALIDARG; |
| 161 *unknown = NULL; | 161 *unknown = NULL; |
| 162 return E_NOTIMPL; | 162 return E_NOTIMPL; |
| 163 } | 163 } |
| 164 | 164 |
| 165 STDMETHODIMP TSFTextStore::GetEndACP(LONG* acp) { | 165 STDMETHODIMP TextStore::GetEndACP(LONG* acp) { |
| 166 if (!acp) | 166 if (!acp) |
| 167 return E_INVALIDARG; | 167 return E_INVALIDARG; |
| 168 if (!HasReadLock()) | 168 if (!HasReadLock()) |
| 169 return TS_E_NOLOCK; | 169 return TS_E_NOLOCK; |
| 170 *acp = static_cast<LONG>(string_buffer_.size()); | 170 *acp = static_cast<LONG>(string_buffer_.size()); |
| 171 return S_OK; | 171 return S_OK; |
| 172 } | 172 } |
| 173 | 173 |
| 174 STDMETHODIMP TSFTextStore::GetFormattedText(LONG acp_start, LONG acp_end, | 174 STDMETHODIMP TextStore::GetFormattedText(LONG acp_start, |
| 175 IDataObject** data_object) { | 175 LONG acp_end, |
| 176 IDataObject** data_object) { |
| 176 NOTIMPLEMENTED(); | 177 NOTIMPLEMENTED(); |
| 177 return E_NOTIMPL; | 178 return E_NOTIMPL; |
| 178 } | 179 } |
| 179 | 180 |
| 180 STDMETHODIMP TSFTextStore::GetScreenExt(TsViewCookie view_cookie, RECT* rect) { | 181 STDMETHODIMP TextStore::GetScreenExt(TsViewCookie view_cookie, RECT* rect) { |
| 181 if (view_cookie != kViewCookie) | 182 if (view_cookie != kViewCookie) |
| 182 return E_INVALIDARG; | 183 return E_INVALIDARG; |
| 183 if (!rect) | 184 if (!rect) |
| 184 return E_INVALIDARG; | 185 return E_INVALIDARG; |
| 185 | 186 |
| 186 // {0, 0, 0, 0} means that the document rect is not currently displayed. | 187 // {0, 0, 0, 0} means that the document rect is not currently displayed. |
| 187 SetRect(rect, 0, 0, 0, 0); | 188 SetRect(rect, 0, 0, 0, 0); |
| 188 | 189 |
| 189 RECT client_rect = {}; | 190 RECT client_rect = {}; |
| 190 if (!GetClientRect(window_handle_, &client_rect)) | 191 if (!GetClientRect(window_handle_, &client_rect)) |
| 191 return E_FAIL; | 192 return E_FAIL; |
| 192 POINT left_top = {client_rect.left, client_rect.top}; | 193 POINT left_top = {client_rect.left, client_rect.top}; |
| 193 POINT right_bottom = {client_rect.right, client_rect.bottom}; | 194 POINT right_bottom = {client_rect.right, client_rect.bottom}; |
| 194 if (!ClientToScreen(window_handle_, &left_top)) | 195 if (!ClientToScreen(window_handle_, &left_top)) |
| 195 return E_FAIL; | 196 return E_FAIL; |
| 196 if (!ClientToScreen(window_handle_, &right_bottom)) | 197 if (!ClientToScreen(window_handle_, &right_bottom)) |
| 197 return E_FAIL; | 198 return E_FAIL; |
| 198 | 199 |
| 199 rect->left = left_top.x; | 200 rect->left = left_top.x; |
| 200 rect->top = left_top.y; | 201 rect->top = left_top.y; |
| 201 rect->right = right_bottom.x; | 202 rect->right = right_bottom.x; |
| 202 rect->bottom = right_bottom.y; | 203 rect->bottom = right_bottom.y; |
| 203 return S_OK; | 204 return S_OK; |
| 204 } | 205 } |
| 205 | 206 |
| 206 STDMETHODIMP TSFTextStore::GetSelection(ULONG selection_index, | 207 STDMETHODIMP TextStore::GetSelection(ULONG selection_index, |
| 207 ULONG selection_buffer_size, | 208 ULONG selection_buffer_size, |
| 208 TS_SELECTION_ACP* selection_buffer, | 209 TS_SELECTION_ACP* selection_buffer, |
| 209 ULONG* fetched_count) { | 210 ULONG* fetched_count) { |
| 210 if (!selection_buffer) | 211 if (!selection_buffer) |
| 211 return E_INVALIDARG; | 212 return E_INVALIDARG; |
| 212 if (!fetched_count) | 213 if (!fetched_count) |
| 213 return E_INVALIDARG; | 214 return E_INVALIDARG; |
| 214 if (!HasReadLock()) | 215 if (!HasReadLock()) |
| 215 return TS_E_NOLOCK; | 216 return TS_E_NOLOCK; |
| 216 *fetched_count = 0; | 217 *fetched_count = 0; |
| 217 if ((selection_buffer_size > 0) && | 218 if ((selection_buffer_size > 0) && |
| 218 ((selection_index == 0) || (selection_index == TS_DEFAULT_SELECTION))) { | 219 ((selection_index == 0) || (selection_index == TS_DEFAULT_SELECTION))) { |
| 219 selection_buffer[0].acpStart = selection_start_; | 220 selection_buffer[0].acpStart = selection_start_; |
| 220 selection_buffer[0].acpEnd = selection_end_; | 221 selection_buffer[0].acpEnd = selection_end_; |
| 221 selection_buffer[0].style.ase = TS_AE_END; | 222 selection_buffer[0].style.ase = TS_AE_END; |
| 222 selection_buffer[0].style.fInterimChar = FALSE; | 223 selection_buffer[0].style.fInterimChar = FALSE; |
| 223 *fetched_count = 1; | 224 *fetched_count = 1; |
| 224 } | 225 } |
| 225 return S_OK; | 226 return S_OK; |
| 226 } | 227 } |
| 227 | 228 |
| 228 STDMETHODIMP TSFTextStore::GetStatus(TS_STATUS* status) { | 229 STDMETHODIMP TextStore::GetStatus(TS_STATUS* status) { |
| 229 if (!status) | 230 if (!status) |
| 230 return E_INVALIDARG; | 231 return E_INVALIDARG; |
| 231 | 232 |
| 232 status->dwDynamicFlags = 0; | 233 status->dwDynamicFlags = 0; |
| 233 // We use transitory contexts and we don't support hidden text. | 234 // We use transitory contexts and we don't support hidden text. |
| 234 status->dwStaticFlags = TS_SS_TRANSITORY | TS_SS_NOHIDDENTEXT; | 235 status->dwStaticFlags = TS_SS_TRANSITORY | TS_SS_NOHIDDENTEXT; |
| 235 | 236 |
| 236 return S_OK; | 237 return S_OK; |
| 237 } | 238 } |
| 238 | 239 |
| 239 STDMETHODIMP TSFTextStore::GetText(LONG acp_start, | 240 STDMETHODIMP TextStore::GetText(LONG acp_start, |
| 240 LONG acp_end, | 241 LONG acp_end, |
| 241 wchar_t* text_buffer, | 242 wchar_t* text_buffer, |
| 242 ULONG text_buffer_size, | 243 ULONG text_buffer_size, |
| 243 ULONG* text_buffer_copied, | 244 ULONG* text_buffer_copied, |
| 244 TS_RUNINFO* run_info_buffer, | 245 TS_RUNINFO* run_info_buffer, |
| 245 ULONG run_info_buffer_size, | 246 ULONG run_info_buffer_size, |
| 246 ULONG* run_info_buffer_copied, | 247 ULONG* run_info_buffer_copied, |
| 247 LONG* next_acp) { | 248 LONG* next_acp) { |
| 248 if (!text_buffer_copied || !run_info_buffer_copied) | 249 if (!text_buffer_copied || !run_info_buffer_copied) |
| 249 return E_INVALIDARG; | 250 return E_INVALIDARG; |
| 250 if (!text_buffer && text_buffer_size != 0) | 251 if (!text_buffer && text_buffer_size != 0) |
| 251 return E_INVALIDARG; | 252 return E_INVALIDARG; |
| 252 if (!run_info_buffer && run_info_buffer_size != 0) | 253 if (!run_info_buffer && run_info_buffer_size != 0) |
| 253 return E_INVALIDARG; | 254 return E_INVALIDARG; |
| 254 if (!next_acp) | 255 if (!next_acp) |
| 255 return E_INVALIDARG; | 256 return E_INVALIDARG; |
| 256 if (!HasReadLock()) | 257 if (!HasReadLock()) |
| 257 return TF_E_NOLOCK; | 258 return TF_E_NOLOCK; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 274 if (run_info_buffer_size) { | 275 if (run_info_buffer_size) { |
| 275 run_info_buffer[0].uCount = *text_buffer_copied; | 276 run_info_buffer[0].uCount = *text_buffer_copied; |
| 276 run_info_buffer[0].type = TS_RT_PLAIN; | 277 run_info_buffer[0].type = TS_RT_PLAIN; |
| 277 *run_info_buffer_copied = 1; | 278 *run_info_buffer_copied = 1; |
| 278 } | 279 } |
| 279 | 280 |
| 280 *next_acp = acp_end; | 281 *next_acp = acp_end; |
| 281 return S_OK; | 282 return S_OK; |
| 282 } | 283 } |
| 283 | 284 |
| 284 STDMETHODIMP TSFTextStore::GetTextExt(TsViewCookie view_cookie, | 285 STDMETHODIMP TextStore::GetTextExt(TsViewCookie view_cookie, |
| 285 LONG acp_start, | 286 LONG acp_start, |
| 286 LONG acp_end, | 287 LONG acp_end, |
| 287 RECT* rect, | 288 RECT* rect, |
| 288 BOOL* clipped) { | 289 BOOL* clipped) { |
| 289 if (!rect || !clipped) | 290 if (!rect || !clipped) |
| 290 return E_INVALIDARG; | 291 return E_INVALIDARG; |
| 291 if (view_cookie != kViewCookie) | 292 if (view_cookie != kViewCookie) |
| 292 return E_INVALIDARG; | 293 return E_INVALIDARG; |
| 293 if (!HasReadLock()) | 294 if (!HasReadLock()) |
| 294 return TS_E_NOLOCK; | 295 return TS_E_NOLOCK; |
| 295 if (!((static_cast<LONG>(committed_size_) <= acp_start) && | 296 if (!((static_cast<LONG>(committed_size_) <= acp_start) && |
| 296 (acp_start <= acp_end) && | 297 (acp_start <= acp_end) && |
| 297 (acp_end <= static_cast<LONG>(string_buffer_.size())))) { | 298 (acp_end <= static_cast<LONG>(string_buffer_.size())))) { |
| 298 return TS_E_INVALIDPOS; | 299 return TS_E_INVALIDPOS; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 else | 350 else |
| 350 return TS_E_NOLAYOUT; | 351 return TS_E_NOLAYOUT; |
| 351 } | 352 } |
| 352 } | 353 } |
| 353 | 354 |
| 354 *rect = result; | 355 *rect = result; |
| 355 *clipped = FALSE; | 356 *clipped = FALSE; |
| 356 return S_OK; | 357 return S_OK; |
| 357 } | 358 } |
| 358 | 359 |
| 359 STDMETHODIMP TSFTextStore::GetWnd(TsViewCookie view_cookie, | 360 STDMETHODIMP TextStore::GetWnd(TsViewCookie view_cookie, |
| 360 HWND* window_handle) { | 361 HWND* window_handle) { |
| 361 if (!window_handle) | 362 if (!window_handle) |
| 362 return E_INVALIDARG; | 363 return E_INVALIDARG; |
| 363 if (view_cookie != kViewCookie) | 364 if (view_cookie != kViewCookie) |
| 364 return E_INVALIDARG; | 365 return E_INVALIDARG; |
| 365 *window_handle = window_handle_; | 366 *window_handle = window_handle_; |
| 366 return S_OK; | 367 return S_OK; |
| 367 } | 368 } |
| 368 | 369 |
| 369 STDMETHODIMP TSFTextStore::InsertEmbedded(DWORD flags, | 370 STDMETHODIMP TextStore::InsertEmbedded(DWORD flags, |
| 370 LONG acp_start, | 371 LONG acp_start, |
| 371 LONG acp_end, | 372 LONG acp_end, |
| 372 IDataObject* data_object, | 373 IDataObject* data_object, |
| 373 TS_TEXTCHANGE* change) { | 374 TS_TEXTCHANGE* change) { |
| 374 // We don't support any embedded objects. | 375 // We don't support any embedded objects. |
| 375 NOTIMPLEMENTED(); | 376 NOTIMPLEMENTED(); |
| 376 return E_NOTIMPL; | 377 return E_NOTIMPL; |
| 377 } | 378 } |
| 378 | 379 |
| 379 STDMETHODIMP TSFTextStore::InsertEmbeddedAtSelection(DWORD flags, | 380 STDMETHODIMP TextStore::InsertEmbeddedAtSelection(DWORD flags, |
| 380 IDataObject* data_object, | 381 IDataObject* data_object, |
| 381 LONG* acp_start, | 382 LONG* acp_start, |
| 382 LONG* acp_end, | 383 LONG* acp_end, |
| 383 TS_TEXTCHANGE* change) { | 384 TS_TEXTCHANGE* change) { |
| 384 // We don't support any embedded objects. | 385 // We don't support any embedded objects. |
| 385 NOTIMPLEMENTED(); | 386 NOTIMPLEMENTED(); |
| 386 return E_NOTIMPL; | 387 return E_NOTIMPL; |
| 387 } | 388 } |
| 388 | 389 |
| 389 STDMETHODIMP TSFTextStore::InsertTextAtSelection(DWORD flags, | 390 STDMETHODIMP TextStore::InsertTextAtSelection(DWORD flags, |
| 390 const wchar_t* text_buffer, | 391 const wchar_t* text_buffer, |
| 391 ULONG text_buffer_size, | 392 ULONG text_buffer_size, |
| 392 LONG* acp_start, | 393 LONG* acp_start, |
| 393 LONG* acp_end, | 394 LONG* acp_end, |
| 394 TS_TEXTCHANGE* text_change) { | 395 TS_TEXTCHANGE* text_change) { |
| 395 const LONG start_pos = selection_start_; | 396 const LONG start_pos = selection_start_; |
| 396 const LONG end_pos = selection_end_; | 397 const LONG end_pos = selection_end_; |
| 397 const LONG new_end_pos = start_pos + text_buffer_size; | 398 const LONG new_end_pos = start_pos + text_buffer_size; |
| 398 | 399 |
| 399 if (flags & TS_IAS_QUERYONLY) { | 400 if (flags & TS_IAS_QUERYONLY) { |
| 400 if (!HasReadLock()) | 401 if (!HasReadLock()) |
| 401 return TS_E_NOLOCK; | 402 return TS_E_NOLOCK; |
| 402 if (acp_start) | 403 if (acp_start) |
| 403 *acp_start = start_pos; | 404 *acp_start = start_pos; |
| 404 if (acp_end) | 405 if (acp_end) |
| (...skipping 17 matching lines...) Expand all Loading... |
| 422 if (text_change) { | 423 if (text_change) { |
| 423 text_change->acpStart = start_pos; | 424 text_change->acpStart = start_pos; |
| 424 text_change->acpOldEnd = end_pos; | 425 text_change->acpOldEnd = end_pos; |
| 425 text_change->acpNewEnd = new_end_pos; | 426 text_change->acpNewEnd = new_end_pos; |
| 426 } | 427 } |
| 427 selection_start_ = start_pos; | 428 selection_start_ = start_pos; |
| 428 selection_end_ = new_end_pos; | 429 selection_end_ = new_end_pos; |
| 429 return S_OK; | 430 return S_OK; |
| 430 } | 431 } |
| 431 | 432 |
| 432 STDMETHODIMP TSFTextStore::QueryInsert( | 433 STDMETHODIMP TextStore::QueryInsert( |
| 433 LONG acp_test_start, | 434 LONG acp_test_start, |
| 434 LONG acp_test_end, | 435 LONG acp_test_end, |
| 435 ULONG text_size, | 436 ULONG text_size, |
| 436 LONG* acp_result_start, | 437 LONG* acp_result_start, |
| 437 LONG* acp_result_end) { | 438 LONG* acp_result_end) { |
| 438 if (!acp_result_start || !acp_result_end || acp_test_start > acp_test_end) | 439 if (!acp_result_start || !acp_result_end || acp_test_start > acp_test_end) |
| 439 return E_INVALIDARG; | 440 return E_INVALIDARG; |
| 440 const LONG committed_size = static_cast<LONG>(committed_size_); | 441 const LONG committed_size = static_cast<LONG>(committed_size_); |
| 441 const LONG buffer_size = static_cast<LONG>(string_buffer_.size()); | 442 const LONG buffer_size = static_cast<LONG>(string_buffer_.size()); |
| 442 *acp_result_start = std::min(std::max(committed_size, acp_test_start), | 443 *acp_result_start = std::min(std::max(committed_size, acp_test_start), |
| 443 buffer_size); | 444 buffer_size); |
| 444 *acp_result_end = std::min(std::max(committed_size, acp_test_end), | 445 *acp_result_end = std::min(std::max(committed_size, acp_test_end), |
| 445 buffer_size); | 446 buffer_size); |
| 446 return S_OK; | 447 return S_OK; |
| 447 } | 448 } |
| 448 | 449 |
| 449 STDMETHODIMP TSFTextStore::QueryInsertEmbedded(const GUID* service, | 450 STDMETHODIMP TextStore::QueryInsertEmbedded(const GUID* service, |
| 450 const FORMATETC* format, | 451 const FORMATETC* format, |
| 451 BOOL* insertable) { | 452 BOOL* insertable) { |
| 452 if (!format) | 453 if (!format) |
| 453 return E_INVALIDARG; | 454 return E_INVALIDARG; |
| 454 // We don't support any embedded objects. | 455 // We don't support any embedded objects. |
| 455 if (insertable) | 456 if (insertable) |
| 456 *insertable = FALSE; | 457 *insertable = FALSE; |
| 457 return S_OK; | 458 return S_OK; |
| 458 } | 459 } |
| 459 | 460 |
| 460 STDMETHODIMP TSFTextStore::RequestAttrsAtPosition( | 461 STDMETHODIMP TextStore::RequestAttrsAtPosition( |
| 461 LONG acp_pos, | 462 LONG acp_pos, |
| 462 ULONG attribute_buffer_size, | 463 ULONG attribute_buffer_size, |
| 463 const TS_ATTRID* attribute_buffer, | 464 const TS_ATTRID* attribute_buffer, |
| 464 DWORD flags) { | 465 DWORD flags) { |
| 465 // We don't support any document attributes. | 466 // We don't support any document attributes. |
| 466 // This method just returns S_OK, and the subsequently called | 467 // This method just returns S_OK, and the subsequently called |
| 467 // RetrieveRequestedAttrs() returns 0 as the number of supported attributes. | 468 // RetrieveRequestedAttrs() returns 0 as the number of supported attributes. |
| 468 return S_OK; | 469 return S_OK; |
| 469 } | 470 } |
| 470 | 471 |
| 471 STDMETHODIMP TSFTextStore::RequestAttrsTransitioningAtPosition( | 472 STDMETHODIMP TextStore::RequestAttrsTransitioningAtPosition( |
| 472 LONG acp_pos, | 473 LONG acp_pos, |
| 473 ULONG attribute_buffer_size, | 474 ULONG attribute_buffer_size, |
| 474 const TS_ATTRID* attribute_buffer, | 475 const TS_ATTRID* attribute_buffer, |
| 475 DWORD flags) { | 476 DWORD flags) { |
| 476 // We don't support any document attributes. | 477 // We don't support any document attributes. |
| 477 // This method just returns S_OK, and the subsequently called | 478 // This method just returns S_OK, and the subsequently called |
| 478 // RetrieveRequestedAttrs() returns 0 as the number of supported attributes. | 479 // RetrieveRequestedAttrs() returns 0 as the number of supported attributes. |
| 479 return S_OK; | 480 return S_OK; |
| 480 } | 481 } |
| 481 | 482 |
| 482 STDMETHODIMP TSFTextStore::RequestLock(DWORD lock_flags, HRESULT* result) { | 483 STDMETHODIMP TextStore::RequestLock(DWORD lock_flags, HRESULT* result) { |
| 483 if (!text_store_acp_sink_.get()) | 484 if (!text_store_acp_sink_.get()) |
| 484 return E_FAIL; | 485 return E_FAIL; |
| 485 if (!result) | 486 if (!result) |
| 486 return E_INVALIDARG; | 487 return E_INVALIDARG; |
| 487 | 488 |
| 488 if (current_lock_type_ != 0) { | 489 if (current_lock_type_ != 0) { |
| 489 if (lock_flags & TS_LF_SYNC) { | 490 if (lock_flags & TS_LF_SYNC) { |
| 490 // Can't lock synchronously. | 491 // Can't lock synchronously. |
| 491 *result = TS_E_SYNCHRONOUS; | 492 *result = TS_E_SYNCHRONOUS; |
| 492 return S_OK; | 493 return S_OK; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 textChange.acpStart = 0; | 568 textChange.acpStart = 0; |
| 568 textChange.acpOldEnd = new_committed_size; | 569 textChange.acpOldEnd = new_committed_size; |
| 569 textChange.acpNewEnd = 0; | 570 textChange.acpNewEnd = 0; |
| 570 text_store_acp_sink_->OnTextChange(0, &textChange); | 571 text_store_acp_sink_->OnTextChange(0, &textChange); |
| 571 } | 572 } |
| 572 } | 573 } |
| 573 | 574 |
| 574 return S_OK; | 575 return S_OK; |
| 575 } | 576 } |
| 576 | 577 |
| 577 STDMETHODIMP TSFTextStore::RequestSupportedAttrs( | 578 STDMETHODIMP TextStore::RequestSupportedAttrs( |
| 578 DWORD /* flags */, // Seems that we should ignore this. | 579 DWORD /* flags */, // Seems that we should ignore this. |
| 579 ULONG attribute_buffer_size, | 580 ULONG attribute_buffer_size, |
| 580 const TS_ATTRID* attribute_buffer) { | 581 const TS_ATTRID* attribute_buffer) { |
| 581 if (!attribute_buffer) | 582 if (!attribute_buffer) |
| 582 return E_INVALIDARG; | 583 return E_INVALIDARG; |
| 583 if (!input_scope_) | 584 if (!input_scope_) |
| 584 return E_FAIL; | 585 return E_FAIL; |
| 585 // We support only input scope attribute. | 586 // We support only input scope attribute. |
| 586 for (size_t i = 0; i < attribute_buffer_size; ++i) { | 587 for (size_t i = 0; i < attribute_buffer_size; ++i) { |
| 587 if (IsEqualGUID(GUID_PROP_INPUTSCOPE, attribute_buffer[i])) | 588 if (IsEqualGUID(GUID_PROP_INPUTSCOPE, attribute_buffer[i])) |
| 588 return S_OK; | 589 return S_OK; |
| 589 } | 590 } |
| 590 return E_FAIL; | 591 return E_FAIL; |
| 591 } | 592 } |
| 592 | 593 |
| 593 STDMETHODIMP TSFTextStore::RetrieveRequestedAttrs( | 594 STDMETHODIMP TextStore::RetrieveRequestedAttrs( |
| 594 ULONG attribute_buffer_size, | 595 ULONG attribute_buffer_size, |
| 595 TS_ATTRVAL* attribute_buffer, | 596 TS_ATTRVAL* attribute_buffer, |
| 596 ULONG* attribute_buffer_copied) { | 597 ULONG* attribute_buffer_copied) { |
| 597 if (!attribute_buffer_copied) | 598 if (!attribute_buffer_copied) |
| 598 return E_INVALIDARG; | 599 return E_INVALIDARG; |
| 599 *attribute_buffer_copied = 0; | 600 *attribute_buffer_copied = 0; |
| 600 if (!attribute_buffer) | 601 if (!attribute_buffer) |
| 601 return E_INVALIDARG; | 602 return E_INVALIDARG; |
| 602 if (!input_scope_) | 603 if (!input_scope_) |
| 603 return E_UNEXPECTED; | 604 return E_UNEXPECTED; |
| 604 // We support only input scope attribute. | 605 // We support only input scope attribute. |
| 605 *attribute_buffer_copied = 0; | 606 *attribute_buffer_copied = 0; |
| 606 if (attribute_buffer_size == 0) | 607 if (attribute_buffer_size == 0) |
| 607 return S_OK; | 608 return S_OK; |
| 608 | 609 |
| 609 attribute_buffer[0].dwOverlapId = 0; | 610 attribute_buffer[0].dwOverlapId = 0; |
| 610 attribute_buffer[0].idAttr = GUID_PROP_INPUTSCOPE; | 611 attribute_buffer[0].idAttr = GUID_PROP_INPUTSCOPE; |
| 611 attribute_buffer[0].varValue.vt = VT_UNKNOWN; | 612 attribute_buffer[0].varValue.vt = VT_UNKNOWN; |
| 612 attribute_buffer[0].varValue.punkVal = input_scope_.get(); | 613 attribute_buffer[0].varValue.punkVal = input_scope_.get(); |
| 613 attribute_buffer[0].varValue.punkVal->AddRef(); | 614 attribute_buffer[0].varValue.punkVal->AddRef(); |
| 614 *attribute_buffer_copied = 1; | 615 *attribute_buffer_copied = 1; |
| 615 return S_OK; | 616 return S_OK; |
| 616 } | 617 } |
| 617 | 618 |
| 618 STDMETHODIMP TSFTextStore::SetSelection( | 619 STDMETHODIMP TextStore::SetSelection( |
| 619 ULONG selection_buffer_size, | 620 ULONG selection_buffer_size, |
| 620 const TS_SELECTION_ACP* selection_buffer) { | 621 const TS_SELECTION_ACP* selection_buffer) { |
| 621 if (!HasReadWriteLock()) | 622 if (!HasReadWriteLock()) |
| 622 return TF_E_NOLOCK; | 623 return TF_E_NOLOCK; |
| 623 if (selection_buffer_size > 0) { | 624 if (selection_buffer_size > 0) { |
| 624 const LONG start_pos = selection_buffer[0].acpStart; | 625 const LONG start_pos = selection_buffer[0].acpStart; |
| 625 const LONG end_pos = selection_buffer[0].acpEnd; | 626 const LONG end_pos = selection_buffer[0].acpEnd; |
| 626 if (!((static_cast<LONG>(committed_size_) <= start_pos) && | 627 if (!((static_cast<LONG>(committed_size_) <= start_pos) && |
| 627 (start_pos <= end_pos) && | 628 (start_pos <= end_pos) && |
| 628 (end_pos <= static_cast<LONG>(string_buffer_.size())))) { | 629 (end_pos <= static_cast<LONG>(string_buffer_.size())))) { |
| 629 return TF_E_INVALIDPOS; | 630 return TF_E_INVALIDPOS; |
| 630 } | 631 } |
| 631 selection_start_ = start_pos; | 632 selection_start_ = start_pos; |
| 632 selection_end_ = end_pos; | 633 selection_end_ = end_pos; |
| 633 } | 634 } |
| 634 return S_OK; | 635 return S_OK; |
| 635 } | 636 } |
| 636 | 637 |
| 637 STDMETHODIMP TSFTextStore::SetText(DWORD flags, | 638 STDMETHODIMP TextStore::SetText(DWORD flags, |
| 638 LONG acp_start, | 639 LONG acp_start, |
| 639 LONG acp_end, | 640 LONG acp_end, |
| 640 const wchar_t* text_buffer, | 641 const wchar_t* text_buffer, |
| 641 ULONG text_buffer_size, | 642 ULONG text_buffer_size, |
| 642 TS_TEXTCHANGE* text_change) { | 643 TS_TEXTCHANGE* text_change) { |
| 643 if (!HasReadWriteLock()) | 644 if (!HasReadWriteLock()) |
| 644 return TS_E_NOLOCK; | 645 return TS_E_NOLOCK; |
| 645 if (!((static_cast<LONG>(committed_size_) <= acp_start) && | 646 if (!((static_cast<LONG>(committed_size_) <= acp_start) && |
| 646 (acp_start <= acp_end) && | 647 (acp_start <= acp_end) && |
| 647 (acp_end <= static_cast<LONG>(string_buffer_.size())))) { | 648 (acp_end <= static_cast<LONG>(string_buffer_.size())))) { |
| 648 return TS_E_INVALIDPOS; | 649 return TS_E_INVALIDPOS; |
| 649 } | 650 } |
| 650 | 651 |
| 651 TS_SELECTION_ACP selection; | 652 TS_SELECTION_ACP selection; |
| 652 selection.acpStart = acp_start; | 653 selection.acpStart = acp_start; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 664 &acp_start, &acp_end, &change); | 665 &acp_start, &acp_end, &change); |
| 665 if (ret != S_OK) | 666 if (ret != S_OK) |
| 666 return ret; | 667 return ret; |
| 667 | 668 |
| 668 if (text_change) | 669 if (text_change) |
| 669 *text_change = change; | 670 *text_change = change; |
| 670 | 671 |
| 671 return S_OK; | 672 return S_OK; |
| 672 } | 673 } |
| 673 | 674 |
| 674 STDMETHODIMP TSFTextStore::UnadviseSink(IUnknown* unknown) { | 675 STDMETHODIMP TextStore::UnadviseSink(IUnknown* unknown) { |
| 675 if (!text_store_acp_sink_.IsSameObject(unknown)) | 676 if (!text_store_acp_sink_.IsSameObject(unknown)) |
| 676 return CONNECT_E_NOCONNECTION; | 677 return CONNECT_E_NOCONNECTION; |
| 677 text_store_acp_sink_.Release(); | 678 text_store_acp_sink_.Release(); |
| 678 text_store_acp_sink_mask_ = 0; | 679 text_store_acp_sink_mask_ = 0; |
| 679 return S_OK; | 680 return S_OK; |
| 680 } | 681 } |
| 681 | 682 |
| 682 STDMETHODIMP TSFTextStore::OnStartComposition( | 683 STDMETHODIMP TextStore::OnStartComposition( |
| 683 ITfCompositionView* composition_view, | 684 ITfCompositionView* composition_view, |
| 684 BOOL* ok) { | 685 BOOL* ok) { |
| 685 if (ok) | 686 if (ok) |
| 686 *ok = TRUE; | 687 *ok = TRUE; |
| 687 return S_OK; | 688 return S_OK; |
| 688 } | 689 } |
| 689 | 690 |
| 690 STDMETHODIMP TSFTextStore::OnUpdateComposition( | 691 STDMETHODIMP TextStore::OnUpdateComposition( |
| 691 ITfCompositionView* composition_view, | 692 ITfCompositionView* composition_view, |
| 692 ITfRange* range) { | 693 ITfRange* range) { |
| 693 return S_OK; | 694 return S_OK; |
| 694 } | 695 } |
| 695 | 696 |
| 696 STDMETHODIMP TSFTextStore::OnEndComposition( | 697 STDMETHODIMP TextStore::OnEndComposition( |
| 697 ITfCompositionView* composition_view) { | 698 ITfCompositionView* composition_view) { |
| 698 return S_OK; | 699 return S_OK; |
| 699 } | 700 } |
| 700 | 701 |
| 701 STDMETHODIMP TSFTextStore::OnEndEdit(ITfContext* context, | 702 STDMETHODIMP TextStore::OnEndEdit(ITfContext* context, |
| 702 TfEditCookie read_only_edit_cookie, | 703 TfEditCookie read_only_edit_cookie, |
| 703 ITfEditRecord* edit_record) { | 704 ITfEditRecord* edit_record) { |
| 704 if (!context || !edit_record) | 705 if (!context || !edit_record) |
| 705 return E_INVALIDARG; | 706 return E_INVALIDARG; |
| 706 if (!GetCompositionStatus(context, read_only_edit_cookie, &committed_size_, | 707 if (!GetCompositionStatus(context, read_only_edit_cookie, &committed_size_, |
| 707 &underlines_)) { | 708 &underlines_)) { |
| 708 return S_OK; | 709 return S_OK; |
| 709 } | 710 } |
| 710 edit_flag_ = true; | 711 edit_flag_ = true; |
| 711 return S_OK; | 712 return S_OK; |
| 712 } | 713 } |
| 713 | 714 |
| 714 bool TSFTextStore::GetDisplayAttribute(TfGuidAtom guid_atom, | 715 bool TextStore::GetDisplayAttribute(TfGuidAtom guid_atom, |
| 715 TF_DISPLAYATTRIBUTE* attribute) { | 716 TF_DISPLAYATTRIBUTE* attribute) { |
| 716 GUID guid; | 717 GUID guid; |
| 717 if (FAILED(category_manager_->GetGUID(guid_atom, &guid))) | 718 if (FAILED(category_manager_->GetGUID(guid_atom, &guid))) |
| 718 return false; | 719 return false; |
| 719 | 720 |
| 720 base::win::ScopedComPtr<ITfDisplayAttributeInfo> display_attribute_info; | 721 base::win::ScopedComPtr<ITfDisplayAttributeInfo> display_attribute_info; |
| 721 if (FAILED(display_attribute_manager_->GetDisplayAttributeInfo( | 722 if (FAILED(display_attribute_manager_->GetDisplayAttributeInfo( |
| 722 guid, display_attribute_info.Receive(), NULL))) { | 723 guid, display_attribute_info.Receive(), NULL))) { |
| 723 return false; | 724 return false; |
| 724 } | 725 } |
| 725 return SUCCEEDED(display_attribute_info->GetAttributeInfo(attribute)); | 726 return SUCCEEDED(display_attribute_info->GetAttributeInfo(attribute)); |
| 726 } | 727 } |
| 727 | 728 |
| 728 bool TSFTextStore::GetCompositionStatus( | 729 bool TextStore::GetCompositionStatus( |
| 729 ITfContext* context, | 730 ITfContext* context, |
| 730 const TfEditCookie read_only_edit_cookie, | 731 const TfEditCookie read_only_edit_cookie, |
| 731 uint32* committed_size, | 732 uint32* committed_size, |
| 732 std::vector<metro_viewer::UnderlineInfo>* undelines) { | 733 std::vector<metro_viewer::UnderlineInfo>* undelines) { |
| 733 DCHECK(context); | 734 DCHECK(context); |
| 734 DCHECK(committed_size); | 735 DCHECK(committed_size); |
| 735 DCHECK(undelines); | 736 DCHECK(undelines); |
| 736 const GUID* rgGuids[2] = {&GUID_PROP_COMPOSING, &GUID_PROP_ATTRIBUTE}; | 737 const GUID* rgGuids[2] = {&GUID_PROP_COMPOSING, &GUID_PROP_ATTRIBUTE}; |
| 737 base::win::ScopedComPtr<ITfReadOnlyProperty> track_property; | 738 base::win::ScopedComPtr<ITfReadOnlyProperty> track_property; |
| 738 if (FAILED(context->TrackProperties(rgGuids, 2, NULL, 0, | 739 if (FAILED(context->TrackProperties(rgGuids, 2, NULL, 0, |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 801 metro_viewer::UnderlineInfo underline; | 802 metro_viewer::UnderlineInfo underline; |
| 802 underline.start_offset = start_pos; | 803 underline.start_offset = start_pos; |
| 803 underline.end_offset = start_pos + length; | 804 underline.end_offset = start_pos + length; |
| 804 underline.thick = !!display_attribute.fBoldLine; | 805 underline.thick = !!display_attribute.fBoldLine; |
| 805 undelines->push_back(underline); | 806 undelines->push_back(underline); |
| 806 } | 807 } |
| 807 } | 808 } |
| 808 return true; | 809 return true; |
| 809 } | 810 } |
| 810 | 811 |
| 811 bool TSFTextStore::CancelComposition() { | 812 bool TextStore::CancelComposition() { |
| 812 // If there is an on-going document lock, we must not edit the text. | 813 // If there is an on-going document lock, we must not edit the text. |
| 813 if (edit_flag_) | 814 if (edit_flag_) |
| 814 return false; | 815 return false; |
| 815 | 816 |
| 816 if (string_buffer_.empty()) | 817 if (string_buffer_.empty()) |
| 817 return true; | 818 return true; |
| 818 | 819 |
| 819 // Unlike ImmNotifyIME(NI_COMPOSITIONSTR, CPS_CANCEL, 0) in IMM32, TSF does | 820 // Unlike ImmNotifyIME(NI_COMPOSITIONSTR, CPS_CANCEL, 0) in IMM32, TSF does |
| 820 // not have a dedicated method to cancel composition. However, CUAS actually | 821 // not have a dedicated method to cancel composition. However, CUAS actually |
| 821 // has a protocol conversion from CPS_CANCEL into TSF operations. According | 822 // has a protocol conversion from CPS_CANCEL into TSF operations. According |
| (...skipping 15 matching lines...) Expand all Loading... |
| 837 if (text_store_acp_sink_mask_ & TS_AS_TEXT_CHANGE) { | 838 if (text_store_acp_sink_mask_ & TS_AS_TEXT_CHANGE) { |
| 838 TS_TEXTCHANGE textChange = {}; | 839 TS_TEXTCHANGE textChange = {}; |
| 839 textChange.acpStart = 0; | 840 textChange.acpStart = 0; |
| 840 textChange.acpOldEnd = previous_buffer_size; | 841 textChange.acpOldEnd = previous_buffer_size; |
| 841 textChange.acpNewEnd = 0; | 842 textChange.acpNewEnd = 0; |
| 842 text_store_acp_sink_->OnTextChange(0, &textChange); | 843 text_store_acp_sink_->OnTextChange(0, &textChange); |
| 843 } | 844 } |
| 844 return true; | 845 return true; |
| 845 } | 846 } |
| 846 | 847 |
| 847 bool TSFTextStore::ConfirmComposition() { | 848 bool TextStore::ConfirmComposition() { |
| 848 // If there is an on-going document lock, we must not edit the text. | 849 // If there is an on-going document lock, we must not edit the text. |
| 849 if (edit_flag_) | 850 if (edit_flag_) |
| 850 return false; | 851 return false; |
| 851 | 852 |
| 852 if (string_buffer_.empty()) | 853 if (string_buffer_.empty()) |
| 853 return true; | 854 return true; |
| 854 | 855 |
| 855 // See the comment in TSFTextStore::CancelComposition. | 856 // See the comment in TextStore::CancelComposition. |
| 856 // This logic is based on the observation about how to emulate | 857 // This logic is based on the observation about how to emulate |
| 857 // ImmNotifyIME(NI_COMPOSITIONSTR, CPS_COMPLETE, 0) by CUAS. | 858 // ImmNotifyIME(NI_COMPOSITIONSTR, CPS_COMPLETE, 0) by CUAS. |
| 858 | 859 |
| 859 const string16& composition_text = string_buffer_.substr(committed_size_); | 860 const string16& composition_text = string_buffer_.substr(committed_size_); |
| 860 if (!composition_text.empty()) | 861 if (!composition_text.empty()) |
| 861 delegate_->OnTextCommitted(composition_text); | 862 delegate_->OnTextCommitted(composition_text); |
| 862 | 863 |
| 863 const uint32 previous_buffer_size = | 864 const uint32 previous_buffer_size = |
| 864 static_cast<uint32>(string_buffer_.size()); | 865 static_cast<uint32>(string_buffer_.size()); |
| 865 string_buffer_.clear(); | 866 string_buffer_.clear(); |
| 866 committed_size_ = 0; | 867 committed_size_ = 0; |
| 867 selection_start_ = 0; | 868 selection_start_ = 0; |
| 868 selection_end_ = 0; | 869 selection_end_ = 0; |
| 869 if (text_store_acp_sink_mask_ & TS_AS_SEL_CHANGE) | 870 if (text_store_acp_sink_mask_ & TS_AS_SEL_CHANGE) |
| 870 text_store_acp_sink_->OnSelectionChange(); | 871 text_store_acp_sink_->OnSelectionChange(); |
| 871 if (text_store_acp_sink_mask_ & TS_AS_LAYOUT_CHANGE) | 872 if (text_store_acp_sink_mask_ & TS_AS_LAYOUT_CHANGE) |
| 872 text_store_acp_sink_->OnLayoutChange(TS_LC_CHANGE, 0); | 873 text_store_acp_sink_->OnLayoutChange(TS_LC_CHANGE, 0); |
| 873 if (text_store_acp_sink_mask_ & TS_AS_TEXT_CHANGE) { | 874 if (text_store_acp_sink_mask_ & TS_AS_TEXT_CHANGE) { |
| 874 TS_TEXTCHANGE textChange = {}; | 875 TS_TEXTCHANGE textChange = {}; |
| 875 textChange.acpStart = 0; | 876 textChange.acpStart = 0; |
| 876 textChange.acpOldEnd = previous_buffer_size; | 877 textChange.acpOldEnd = previous_buffer_size; |
| 877 textChange.acpNewEnd = 0; | 878 textChange.acpNewEnd = 0; |
| 878 text_store_acp_sink_->OnTextChange(0, &textChange); | 879 text_store_acp_sink_->OnTextChange(0, &textChange); |
| 879 } | 880 } |
| 880 return true; | 881 return true; |
| 881 } | 882 } |
| 882 | 883 |
| 883 void TSFTextStore::SendOnLayoutChange() { | 884 void TextStore::SendOnLayoutChange() { |
| 884 if (text_store_acp_sink_ && (text_store_acp_sink_mask_ & TS_AS_LAYOUT_CHANGE)) | 885 if (text_store_acp_sink_ && (text_store_acp_sink_mask_ & TS_AS_LAYOUT_CHANGE)) |
| 885 text_store_acp_sink_->OnLayoutChange(TS_LC_CHANGE, 0); | 886 text_store_acp_sink_->OnLayoutChange(TS_LC_CHANGE, 0); |
| 886 } | 887 } |
| 887 | 888 |
| 888 bool TSFTextStore::HasReadLock() const { | 889 bool TextStore::HasReadLock() const { |
| 889 return (current_lock_type_ & TS_LF_READ) == TS_LF_READ; | 890 return (current_lock_type_ & TS_LF_READ) == TS_LF_READ; |
| 890 } | 891 } |
| 891 | 892 |
| 892 bool TSFTextStore::HasReadWriteLock() const { | 893 bool TextStore::HasReadWriteLock() const { |
| 893 return (current_lock_type_ & TS_LF_READWRITE) == TS_LF_READWRITE; | 894 return (current_lock_type_ & TS_LF_READWRITE) == TS_LF_READWRITE; |
| 894 } | 895 } |
| 895 | 896 |
| 896 } // namespace metro_driver | 897 } // namespace metro_driver |
| OLD | NEW |