Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1251)

Unified Diff: win8/metro_driver/ime/text_store.cc

Issue 83233002: Enable basic IME functionality under Ash on Windows (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix warnings (that are treated as an error) on 64-bit build Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « win8/metro_driver/ime/text_store.h ('k') | win8/metro_driver/ime/text_store_delegate.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: win8/metro_driver/ime/text_store.cc
diff --git a/ui/base/ime/win/tsf_text_store.cc b/win8/metro_driver/ime/text_store.cc
similarity index 82%
copy from ui/base/ime/win/tsf_text_store.cc
copy to win8/metro_driver/ime/text_store.cc
index 0ef34b5be89a56b649abc9e3a68e1d0ab4392da4..2465fa6040e6dd29ffca277db4b53d29c90d692c 100644
--- a/ui/base/ime/win/tsf_text_store.cc
+++ b/win8/metro_driver/ime/text_store.cc
@@ -1,9 +1,9 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#define INITGUID // required for GUID_PROP_INPUTSCOPE
-#include "ui/base/ime/win/tsf_text_store.h"
+#include "win8/metro_driver/ime/text_store.h"
#include <InputScope.h>
#include <OleCtl.h>
@@ -11,11 +11,10 @@
#include <algorithm>
#include "base/win/scoped_variant.h"
-#include "ui/base/ime/text_input_client.h"
-#include "ui/base/ime/win/tsf_input_scope.h"
-#include "ui/gfx/rect.h"
+#include "win8/metro_driver/ime/input_scope.h"
+#include "win8/metro_driver/ime/text_store_delegate.h"
-namespace ui {
+namespace metro_driver {
namespace {
// We support only one view.
@@ -23,23 +22,58 @@ const TsViewCookie kViewCookie = 1;
} // namespace
-TSFTextStore::TSFTextStore()
+TSFTextStore::TSFTextStore(HWND window_handle,
+ ITfCategoryMgr* category_manager,
+ ITfDisplayAttributeMgr* display_attribute_manager,
+ ITfInputScope* input_scope,
+ TextStoreDelegate* delegate)
: ref_count_(0),
text_store_acp_sink_mask_(0),
- window_handle_(NULL),
- text_input_client_(NULL),
+ window_handle_(window_handle),
+ delegate_(delegate),
committed_size_(0),
+ selection_start_(0),
+ selection_end_(0),
edit_flag_(false),
- current_lock_type_(0) {
- if (FAILED(category_manager_.CreateInstance(CLSID_TF_CategoryMgr))) {
- LOG(FATAL) << "Failed to initialize CategoryMgr.";
- return;
- }
- if (FAILED(display_attribute_manager_.CreateInstance(
- CLSID_TF_DisplayAttributeMgr))) {
- LOG(FATAL) << "Failed to initialize DisplayAttributeMgr.";
- return;
- }
+ current_lock_type_(0),
+ category_manager_(category_manager),
+ display_attribute_manager_(display_attribute_manager),
+ input_scope_(input_scope) {
+}
+
+// static
+scoped_refptr<TSFTextStore> TSFTextStore::Create(
+ HWND window_handle,
+ const std::vector<InputScope>& input_scopes,
+ TextStoreDelegate* delegate) {
+ if (!delegate) {
+ LOG(ERROR) << "|delegate| must be non-NULL.";
+ return scoped_refptr<TSFTextStore>();
+ }
+ base::win::ScopedComPtr<ITfCategoryMgr> category_manager;
+ HRESULT hr = category_manager.CreateInstance(CLSID_TF_CategoryMgr);
+ if (FAILED(hr)) {
+ LOG(ERROR) << "Failed to initialize CategoryMgr. hr = " << hr;
+ return scoped_refptr<TSFTextStore>();
+ }
+ base::win::ScopedComPtr<ITfDisplayAttributeMgr> display_attribute_manager;
+ hr = display_attribute_manager.CreateInstance(CLSID_TF_DisplayAttributeMgr);
+ if (FAILED(hr)) {
+ LOG(ERROR) << "Failed to initialize DisplayAttributeMgr. hr = " << hr;
+ return scoped_refptr<TSFTextStore>();
+ }
+ base::win::ScopedComPtr<ITfInputScope> input_scope =
+ CreteInputScope(input_scopes);
+ if (!input_scope) {
+ LOG(ERROR) << "Failed to initialize InputScope.";
+ return scoped_refptr<TSFTextStore>();
+ }
+ return scoped_refptr<TSFTextStore>(
+ new TSFTextStore(window_handle,
+ category_manager,
+ display_attribute_manager,
+ input_scope,
+ delegate));
}
TSFTextStore::~TSFTextStore() {
@@ -147,7 +181,7 @@ STDMETHODIMP TSFTextStore::GetEndACP(LONG* acp) {
return E_INVALIDARG;
if (!HasReadLock())
return TS_E_NOLOCK;
- *acp = string_buffer_.size();
+ *acp = static_cast<LONG>(string_buffer_.size());
return S_OK;
}
@@ -166,13 +200,6 @@ STDMETHODIMP TSFTextStore::GetScreenExt(TsViewCookie view_cookie, RECT* rect) {
// {0, 0, 0, 0} means that the document rect is not currently displayed.
SetRect(rect, 0, 0, 0, 0);
- if (!IsWindow(window_handle_))
- return E_FAIL;
-
- // Currently ui::TextInputClient does not expose the document rect. So use
- // the Win32 client rectangle instead.
- // TODO(yukawa): Upgrade TextInputClient so that the client can retrieve the
- // document rectangle.
RECT client_rect = {};
if (!GetClientRect(window_handle_, &client_rect))
return E_FAIL;
@@ -203,8 +230,8 @@ STDMETHODIMP TSFTextStore::GetSelection(ULONG selection_index,
*fetched_count = 0;
if ((selection_buffer_size > 0) &&
((selection_index == 0) || (selection_index == TS_DEFAULT_SELECTION))) {
- selection_buffer[0].acpStart = selection_.start();
- selection_buffer[0].acpEnd = selection_.end();
+ selection_buffer[0].acpStart = selection_start_;
+ selection_buffer[0].acpEnd = selection_end_;
selection_buffer[0].style.ase = TS_AE_END;
selection_buffer[0].style.fInterimChar = FALSE;
*fetched_count = 1;
@@ -242,7 +269,7 @@ STDMETHODIMP TSFTextStore::GetText(LONG acp_start,
return E_INVALIDARG;
if (!HasReadLock())
return TF_E_NOLOCK;
- const LONG string_buffer_size = string_buffer_.size();
+ const LONG string_buffer_size = static_cast<LONG>(string_buffer_.size());
if (acp_end == -1)
acp_end = string_buffer_size;
if (!((0 <= acp_start) &&
@@ -276,8 +303,6 @@ STDMETHODIMP TSFTextStore::GetTextExt(TsViewCookie view_cookie,
BOOL* clipped) {
if (!rect || !clipped)
return E_INVALIDARG;
- if (!text_input_client_)
- return E_UNEXPECTED;
if (view_cookie != kViewCookie)
return E_INVALIDARG;
if (!HasReadLock())
@@ -294,7 +319,7 @@ STDMETHODIMP TSFTextStore::GetTextExt(TsViewCookie view_cookie,
// We use RECT instead of gfx::Rect since left position may be bigger than
// right position when composition has multiple lines.
RECT result;
- gfx::Rect tmp_rect;
+ RECT tmp_rect;
const uint32 start_pos = acp_start - committed_size_;
const uint32 end_pos = acp_end - committed_size_;
@@ -305,34 +330,27 @@ STDMETHODIMP TSFTextStore::GetTextExt(TsViewCookie view_cookie,
// But when using Pinin IME of Windows 8, this method is called with the
// equal values of |acp_start| and |acp_end|. So we handle this condition.
if (start_pos == 0) {
- if (text_input_client_->GetCompositionCharacterBounds(0, &tmp_rect)) {
- tmp_rect.set_width(0);
- result = tmp_rect.ToRECT();
+ if (delegate_->GetCompositionCharacterBounds(0, &tmp_rect)) {
+ tmp_rect.right = tmp_rect.right;
+ result = tmp_rect;
} else if (string_buffer_.size() == committed_size_) {
- result = text_input_client_->GetCaretBounds().ToRECT();
+ result = delegate_->GetCaretBounds();
} else {
return TS_E_NOLAYOUT;
}
- } else if (text_input_client_->GetCompositionCharacterBounds(start_pos - 1,
- &tmp_rect)) {
- result.left = tmp_rect.right();
- result.right = tmp_rect.right();
- result.top = tmp_rect.y();
- result.bottom = tmp_rect.bottom();
+ } else if (delegate_->GetCompositionCharacterBounds(start_pos - 1,
+ &tmp_rect)) {
+ tmp_rect.left = tmp_rect.right;
+ result = tmp_rect;
} else {
return TS_E_NOLAYOUT;
}
} else {
- if (text_input_client_->GetCompositionCharacterBounds(start_pos,
- &tmp_rect)) {
- result.left = tmp_rect.x();
- result.top = tmp_rect.y();
- result.right = tmp_rect.right();
- result.bottom = tmp_rect.bottom();
- if (text_input_client_->GetCompositionCharacterBounds(end_pos - 1,
- &tmp_rect)) {
- result.right = tmp_rect.right();
- result.bottom = tmp_rect.bottom();
+ if (delegate_->GetCompositionCharacterBounds(start_pos, &tmp_rect)) {
+ result = tmp_rect;
+ if (delegate_->GetCompositionCharacterBounds(end_pos - 1, &tmp_rect)) {
+ result.right = tmp_rect.right;
+ result.bottom = tmp_rect.bottom;
} else {
// We may not be able to get the last character bounds, so we use the
// first character bounds instead of returning TS_E_NOLAYOUT.
@@ -342,7 +360,7 @@ STDMETHODIMP TSFTextStore::GetTextExt(TsViewCookie view_cookie,
// it's better to return previous caret rectangle instead.
// TODO(nona, kinaba): Remove this hack.
if (start_pos == 0) {
- result = text_input_client_->GetCaretBounds().ToRECT();
+ result = delegate_->GetCaretBounds();
} else {
return TS_E_NOLAYOUT;
}
@@ -390,8 +408,8 @@ STDMETHODIMP TSFTextStore::InsertTextAtSelection(DWORD flags,
LONG* acp_start,
LONG* acp_end,
TS_TEXTCHANGE* text_change) {
- const LONG start_pos = selection_.start();
- const LONG end_pos = selection_.end();
+ const LONG start_pos = selection_start_;
+ const LONG end_pos = selection_end_;
const LONG new_end_pos = start_pos + text_buffer_size;
if (flags & TS_IAS_QUERYONLY) {
@@ -423,8 +441,8 @@ STDMETHODIMP TSFTextStore::InsertTextAtSelection(DWORD flags,
text_change->acpOldEnd = end_pos;
text_change->acpNewEnd = new_end_pos;
}
- selection_.set_start(start_pos);
- selection_.set_end(new_end_pos);
+ selection_start_ = start_pos;
+ selection_end_ = new_end_pos;
return S_OK;
}
@@ -500,7 +518,7 @@ STDMETHODIMP TSFTextStore::RequestLock(DWORD lock_flags, HRESULT* result) {
current_lock_type_ = (lock_flags & TS_LF_READWRITE);
edit_flag_ = false;
- const size_t last_committed_size = committed_size_;
+ const uint32 last_committed_size = committed_size_;
// Grant the lock.
*result = text_store_acp_sink_->OnLockGranted(current_lock_type_);
@@ -516,54 +534,47 @@ STDMETHODIMP TSFTextStore::RequestLock(DWORD lock_flags, HRESULT* result) {
current_lock_type_ = 0;
}
- if (!edit_flag_) {
+ if (!edit_flag_)
return S_OK;
- }
// If the text store is edited in OnLockGranted(), we may need to call
- // TextInputClient::InsertText() or TextInputClient::SetCompositionText().
- const size_t new_committed_size = committed_size_;
+ // TextStoreDelegate::ConfirmComposition() or
+ // TextStoreDelegate::SetComposition().
+ const uint32 new_committed_size = committed_size_;
const string16& new_committed_string =
string_buffer_.substr(last_committed_size,
new_committed_size - last_committed_size);
const string16& composition_string =
string_buffer_.substr(new_committed_size);
- // If there is new committed string, calls TextInputClient::InsertText().
- if ((!new_committed_string.empty()) && text_input_client_) {
- text_input_client_->InsertText(new_committed_string);
- }
+ // If there is new committed string, calls
+ // TextStoreDelegate::ConfirmComposition().
+ if ((!new_committed_string.empty()))
+ delegate_->OnTextCommitted(new_committed_string);
// Calls TextInputClient::SetCompositionText().
- CompositionText composition_text;
- composition_text.text = composition_string;
- composition_text.underlines = composition_undelines_;
+ std::vector<metro_viewer::UnderlineInfo> underlines = underlines_;
// Adjusts the offset.
- for (size_t i = 0; i < composition_text.underlines.size(); ++i) {
- composition_text.underlines[i].start_offset -= new_committed_size;
- composition_text.underlines[i].end_offset -= new_committed_size;
- }
- if (selection_.start() < new_committed_size) {
- composition_text.selection.set_start(0);
- } else {
- composition_text.selection.set_start(
- selection_.start() - new_committed_size);
- }
- if (selection_.end() < new_committed_size) {
- composition_text.selection.set_end(0);
- } else {
- composition_text.selection.set_end(selection_.end() - new_committed_size);
- }
- if (text_input_client_)
- text_input_client_->SetCompositionText(composition_text);
+ for (size_t i = 0; i < underlines_.size(); ++i) {
+ underlines[i].start_offset -= new_committed_size;
+ underlines[i].end_offset -= new_committed_size;
+ }
+ int32 selection_start = 0;
+ int32 selection_end = 0;
+ if (selection_start_ >= new_committed_size)
+ selection_start = selection_start_ - new_committed_size;
+ if (selection_end_ >= new_committed_size)
+ selection_end = selection_end_ - new_committed_size;
+ delegate_->OnCompositionChanged(
+ composition_string, selection_start, selection_end, underlines);
// If there is no composition string, clear the text store status.
// And call OnSelectionChange(), OnLayoutChange(), and OnTextChange().
if ((composition_string.empty()) && (new_committed_size != 0)) {
string_buffer_.clear();
committed_size_ = 0;
- selection_.set_start(0);
- selection_.set_end(0);
+ selection_start_ = 0;
+ selection_end_ = 0;
if (text_store_acp_sink_mask_ & TS_AS_SEL_CHANGE)
text_store_acp_sink_->OnSelectionChange();
if (text_store_acp_sink_mask_ & TS_AS_LAYOUT_CHANGE)
@@ -586,7 +597,7 @@ STDMETHODIMP TSFTextStore::RequestSupportedAttrs(
const TS_ATTRID* attribute_buffer) {
if (!attribute_buffer)
return E_INVALIDARG;
- if (!text_input_client_)
+ if (!input_scope_)
return E_FAIL;
// We support only input scope attribute.
for (size_t i = 0; i < attribute_buffer_size; ++i) {
@@ -602,9 +613,10 @@ STDMETHODIMP TSFTextStore::RetrieveRequestedAttrs(
ULONG* attribute_buffer_copied) {
if (!attribute_buffer_copied)
return E_INVALIDARG;
+ *attribute_buffer_copied = 0;
if (!attribute_buffer)
return E_INVALIDARG;
- if (!text_input_client_)
+ if (!input_scope_)
return E_UNEXPECTED;
// We support only input scope attribute.
*attribute_buffer_copied = 0;
@@ -614,9 +626,7 @@ STDMETHODIMP TSFTextStore::RetrieveRequestedAttrs(
attribute_buffer[0].dwOverlapId = 0;
attribute_buffer[0].idAttr = GUID_PROP_INPUTSCOPE;
attribute_buffer[0].varValue.vt = VT_UNKNOWN;
- attribute_buffer[0].varValue.punkVal = tsf_inputscope::CreateInputScope(
- text_input_client_->GetTextInputType(),
- text_input_client_->GetTextInputMode());
+ attribute_buffer[0].varValue.punkVal = input_scope_.get();
attribute_buffer[0].varValue.punkVal->AddRef();
*attribute_buffer_copied = 1;
return S_OK;
@@ -635,8 +645,8 @@ STDMETHODIMP TSFTextStore::SetSelection(
(end_pos <= static_cast<LONG>(string_buffer_.size())))) {
return TF_E_INVALIDPOS;
}
- selection_.set_start(start_pos);
- selection_.set_end(end_pos);
+ selection_start_ = start_pos;
+ selection_end_ = end_pos;
}
return S_OK;
}
@@ -706,19 +716,14 @@ STDMETHODIMP TSFTextStore::OnEndComposition(
}
STDMETHODIMP TSFTextStore::OnEndEdit(ITfContext* context,
- TfEditCookie read_only_edit_cookie,
- ITfEditRecord* edit_record) {
+ TfEditCookie read_only_edit_cookie,
+ ITfEditRecord* edit_record) {
if (!context || !edit_record)
return E_INVALIDARG;
-
- size_t committed_size;
- CompositionUnderlines undelines;
- if (!GetCompositionStatus(context, read_only_edit_cookie, &committed_size,
- &undelines)) {
+ if (!GetCompositionStatus(context, read_only_edit_cookie, &committed_size_,
+ &underlines_)) {
return S_OK;
}
- composition_undelines_ = undelines;
- committed_size_ = committed_size;
edit_flag_ = true;
return S_OK;
}
@@ -740,8 +745,8 @@ bool TSFTextStore::GetDisplayAttribute(TfGuidAtom guid_atom,
bool TSFTextStore::GetCompositionStatus(
ITfContext* context,
const TfEditCookie read_only_edit_cookie,
- size_t* committed_size,
- CompositionUnderlines* undelines) {
+ uint32* committed_size,
+ std::vector<metro_viewer::UnderlineInfo>* undelines) {
DCHECK(context);
DCHECK(committed_size);
DCHECK(undelines);
@@ -810,33 +815,16 @@ bool TSFTextStore::GetCompositionStatus(
if (*committed_size < static_cast<size_t>(start_pos + length))
*committed_size = start_pos + length;
} else {
- CompositionUnderline underline;
+ metro_viewer::UnderlineInfo underline;
underline.start_offset = start_pos;
underline.end_offset = start_pos + length;
- underline.color = SK_ColorBLACK;
- if (has_display_attribute)
- underline.thick = !!display_attribute.fBoldLine;
+ underline.thick = !!display_attribute.fBoldLine;
undelines->push_back(underline);
}
}
return true;
}
-void TSFTextStore::SetFocusedTextInputClient(
- HWND focused_window,
- TextInputClient* text_input_client) {
- window_handle_ = focused_window;
- text_input_client_ = text_input_client;
-}
-
-void TSFTextStore::RemoveFocusedTextInputClient(
- TextInputClient* text_input_client) {
- if (text_input_client_ == text_input_client) {
- window_handle_ = NULL;
- text_input_client_ = NULL;
- }
-}
-
bool TSFTextStore::CancelComposition() {
// If there is an on-going document lock, we must not edit the text.
if (edit_flag_)
@@ -853,11 +841,12 @@ bool TSFTextStore::CancelComposition() {
// we use the same operation to cancel composition here to minimize the risk
// of potential compatibility issues.
- const size_t previous_buffer_size = string_buffer_.size();
+ const uint32 previous_buffer_size =
+ static_cast<uint32>(string_buffer_.size());
string_buffer_.clear();
committed_size_ = 0;
- selection_.set_start(0);
- selection_.set_end(0);
+ selection_start_ = 0;
+ selection_end_ = 0;
if (text_store_acp_sink_mask_ & TS_AS_SEL_CHANGE)
text_store_acp_sink_->OnSelectionChange();
if (text_store_acp_sink_mask_ & TS_AS_LAYOUT_CHANGE)
@@ -886,13 +875,14 @@ bool TSFTextStore::ConfirmComposition() {
const string16& composition_text = string_buffer_.substr(committed_size_);
if (!composition_text.empty())
- text_input_client_->InsertText(composition_text);
+ delegate_->OnTextCommitted(composition_text);
- const size_t previous_buffer_size = string_buffer_.size();
+ const uint32 previous_buffer_size =
+ static_cast<uint32>(string_buffer_.size());
string_buffer_.clear();
committed_size_ = 0;
- selection_.set_start(0);
- selection_.set_end(0);
+ selection_start_ = 0;
+ selection_end_ = 0;
if (text_store_acp_sink_mask_ & TS_AS_SEL_CHANGE)
text_store_acp_sink_->OnSelectionChange();
if (text_store_acp_sink_mask_ & TS_AS_LAYOUT_CHANGE)
@@ -920,4 +910,4 @@ bool TSFTextStore::HasReadWriteLock() const {
return (current_lock_type_ & TS_LF_READWRITE) == TS_LF_READWRITE;
}
-} // namespace ui
+} // namespace metro_driver
« no previous file with comments | « win8/metro_driver/ime/text_store.h ('k') | win8/metro_driver/ime/text_store_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698