diff options
author | penghuang@chromium.org <penghuang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-31 09:11:57 +0000 |
---|---|---|
committer | penghuang@chromium.org <penghuang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-31 09:11:57 +0000 |
commit | bb953fdae04e514c4f989e644256f9416e096b64 (patch) | |
tree | 7a342994708efd705c9724b210feb7a91247062f /content/browser/renderer_host | |
parent | 1a771269be8885389b4269e14714759f0fcf8660 (diff) | |
download | chromium_src-bb953fdae04e514c4f989e644256f9416e096b64.zip chromium_src-bb953fdae04e514c4f989e644256f9416e096b64.tar.gz chromium_src-bb953fdae04e514c4f989e644256f9416e096b64.tar.bz2 |
Support IMM32 reconversion on Windows.
BUG=45605
TEST=Tested it with Google Japanese Input method on Win7
Review URL: http://codereview.chromium.org/8294026
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@107934 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/renderer_host')
4 files changed, 157 insertions, 3 deletions
diff --git a/content/browser/renderer_host/render_widget_host_view.cc b/content/browser/renderer_host/render_widget_host_view.cc index 649faec..7fbc61b 100644 --- a/content/browser/renderer_host/render_widget_host_view.cc +++ b/content/browser/renderer_host/render_widget_host_view.cc @@ -45,7 +45,10 @@ void RenderWidgetHostView::GetDefaultScreenInfo( #endif RenderWidgetHostView::RenderWidgetHostView() - : popup_type_(WebKit::WebPopupTypeNone), mouse_locked_(false) { + : popup_type_(WebKit::WebPopupTypeNone), + mouse_locked_(false), + selection_text_offset_(0), + selection_range_(ui::Range::InvalidRange()) { } RenderWidgetHostView::~RenderWidgetHostView() { @@ -55,3 +58,13 @@ RenderWidgetHostView::~RenderWidgetHostView() { void RenderWidgetHostView::SetBackground(const SkBitmap& background) { background_ = background; } + + +void RenderWidgetHostView::SelectionChanged(const string16& text, + size_t offset, + const ui::Range& range) { + selection_text_ = text; + selection_text_offset_ = offset; + selection_range_.set_start(range.start()); + selection_range_.set_end(range.end()); +} diff --git a/content/browser/renderer_host/render_widget_host_view.h b/content/browser/renderer_host/render_widget_host_view.h index c727cf1..7556525 100644 --- a/content/browser/renderer_host/render_widget_host_view.h +++ b/content/browser/renderer_host/render_widget_host_view.h @@ -174,7 +174,7 @@ class RenderWidgetHostView { // Notifies the View that the renderer text selection has changed. virtual void SelectionChanged(const string16& text, size_t offset, - const ui::Range& range) {} + const ui::Range& range); // Notifies the View that the renderer selection bounds has changed. // |start_rect| and |end_rect| are the bounds end of the selection in the @@ -354,6 +354,16 @@ class RenderWidgetHostView { // locked. bool mouse_locked_; + // A buffer containing the text inside and around the current selection range. + string16 selection_text_; + + // The offset of the text stored in |selection_text_| relative to the start of + // the web page. + size_t selection_text_offset_; + + // The current selection range relative to the start of the web page. + ui::Range selection_range_; + private: DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostView); }; diff --git a/content/browser/renderer_host/render_widget_host_view_win.cc b/content/browser/renderer_host/render_widget_host_view_win.cc index fe78c3b..27cbb61 100644 --- a/content/browser/renderer_host/render_widget_host_view_win.cc +++ b/content/browser/renderer_host/render_widget_host_view_win.cc @@ -285,7 +285,8 @@ RenderWidgetHostViewWin::RenderWidgetHostViewWin(RenderWidgetHost* widget) overlay_color_(0), text_input_type_(ui::TEXT_INPUT_TYPE_NONE), is_fullscreen_(false), - ignore_mouse_movement_(true) { + ignore_mouse_movement_(true), + composition_range_(ui::Range::InvalidRange()) { render_widget_host_->SetView(this); registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, @@ -675,6 +676,11 @@ void RenderWidgetHostViewWin::ImeCancelComposition() { ime_input_.CancelIME(m_hWnd); } +void RenderWidgetHostViewWin::ImeCompositionRangeChanged( + const ui::Range& range) { + composition_range_ = range; +} + BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lparam) { if (!webkit::npapi::WebPluginDelegateImpl::IsPluginDelegateWindow(hwnd)) return TRUE; @@ -1279,6 +1285,31 @@ LRESULT RenderWidgetHostViewWin::OnImeEndComposition( return 0; } +LRESULT RenderWidgetHostViewWin::OnImeRequest( + UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled) { + if (!render_widget_host_) { + handled = FALSE; + return 0; + } + + // Should not receive WM_IME_REQUEST message, if IME is disabled. + if (text_input_type_ == ui::TEXT_INPUT_TYPE_NONE || + text_input_type_ == ui::TEXT_INPUT_TYPE_PASSWORD) { + handled = FALSE; + return 0; + } + + switch (wparam) { + case IMR_RECONVERTSTRING: + return OnReconvertString(reinterpret_cast<RECONVERTSTRING*>(lparam)); + case IMR_DOCUMENTFEED: + return OnDocumentFeed(reinterpret_cast<RECONVERTSTRING*>(lparam)); + default: + handled = FALSE; + return 0; + } +} + LRESULT RenderWidgetHostViewWin::OnMouseEvent(UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled) { handled = TRUE; @@ -2026,3 +2057,94 @@ void RenderWidgetHostViewWin::HandleLockedMouseEvent(UINT message, ForwardMouseEventToRenderer(message, wparam, lparam); } + +LRESULT RenderWidgetHostViewWin::OnDocumentFeed(RECONVERTSTRING* reconv) { + size_t target_offset; + size_t target_length; + bool has_composition; + if (!composition_range_.is_empty()) { + target_offset = composition_range_.GetMin(); + target_length = composition_range_.length(); + has_composition = true; + } else if (selection_range_.IsValid()) { + target_offset = selection_range_.GetMin(); + target_length = selection_range_.length(); + has_composition = false; + } else { + return 0; + } + + size_t len = selection_text_.length(); + size_t need_size = sizeof(RECONVERTSTRING) + len * sizeof(WCHAR); + + if (target_offset < selection_text_offset_ || + target_offset + target_length > selection_text_offset_ + len) { + return 0; + } + + if (!reconv) + return need_size; + + if (reconv->dwSize < need_size) + return 0; + + reconv->dwVersion = 0; + reconv->dwStrLen = len; + reconv->dwStrOffset = sizeof(RECONVERTSTRING); + reconv->dwCompStrLen = has_composition ? target_length: 0; + reconv->dwCompStrOffset = + (target_offset - selection_text_offset_) * sizeof(WCHAR); + reconv->dwTargetStrLen = target_length; + reconv->dwTargetStrOffset = reconv->dwCompStrOffset; + memcpy(reinterpret_cast<char*>(reconv) + sizeof(RECONVERTSTRING), + selection_text_.c_str(), len * sizeof(WCHAR)); + + // According to Microsft API document, IMR_RECONVERTSTRING and + // IMR_DOCUMENTFEED should return reconv, but some applications return + // need_size. + return reinterpret_cast<LRESULT>(reconv); +} + +LRESULT RenderWidgetHostViewWin::OnReconvertString(RECONVERTSTRING* reconv) { + // If there is a composition string already, we don't allow reconversion. + if (ime_input_.is_composing()) + return 0; + + if (selection_range_.is_empty()) + return 0; + + if (selection_text_.empty()) + return 0; + + if (selection_range_.GetMin() < selection_text_offset_ || + selection_range_.GetMax() > + selection_text_offset_ + selection_text_.length()) { + return 0; + } + + size_t len = selection_range_.length(); + size_t need_size = sizeof(RECONVERTSTRING) + len * sizeof(WCHAR); + + if (!reconv) + return need_size; + + if (reconv->dwSize < need_size) + return 0; + + reconv->dwVersion = 0; + reconv->dwStrLen = len; + reconv->dwStrOffset = sizeof(RECONVERTSTRING); + reconv->dwCompStrLen = len; + reconv->dwCompStrOffset = 0; + reconv->dwTargetStrLen = len; + reconv->dwTargetStrOffset = 0; + + size_t offset = selection_range_.GetMin() - selection_text_offset_; + memcpy(reinterpret_cast<char*>(reconv) + sizeof(RECONVERTSTRING), + selection_text_.c_str() + offset, len * sizeof(WCHAR)); + + // According to Microsft API document, IMR_RECONVERTSTRING and + // IMR_DOCUMENTFEED should return reconv, but some applications return + // need_size. + return reinterpret_cast<LRESULT>(reconv); +} diff --git a/content/browser/renderer_host/render_widget_host_view_win.h b/content/browser/renderer_host/render_widget_host_view_win.h index f4da850f..0c09e6f 100644 --- a/content/browser/renderer_host/render_widget_host_view_win.h +++ b/content/browser/renderer_host/render_widget_host_view_win.h @@ -104,6 +104,7 @@ class RenderWidgetHostViewWin MESSAGE_HANDLER(WM_IME_STARTCOMPOSITION, OnImeStartComposition) MESSAGE_HANDLER(WM_IME_COMPOSITION, OnImeComposition) MESSAGE_HANDLER(WM_IME_ENDCOMPOSITION, OnImeEndComposition) + MESSAGE_HANDLER(WM_IME_REQUEST, OnImeRequest) MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseEvent) MESSAGE_HANDLER(WM_MOUSELEAVE, OnMouseEvent) MESSAGE_HANDLER(WM_LBUTTONDOWN, OnMouseEvent) @@ -160,6 +161,7 @@ class RenderWidgetHostViewWin virtual void SelectionBoundsChanged(const gfx::Rect& start_rect, const gfx::Rect& end_rect) OVERRIDE; virtual void ImeCancelComposition() OVERRIDE; + virtual void ImeCompositionRangeChanged(const ui::Range& range) OVERRIDE; virtual void DidUpdateBackingStore( const gfx::Rect& scroll_rect, int scroll_dx, int scroll_dy, const std::vector<gfx::Rect>& copy_rects) OVERRIDE; @@ -220,6 +222,8 @@ class RenderWidgetHostViewWin UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled); LRESULT OnImeEndComposition( UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled); + LRESULT OnImeRequest( + UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled); LRESULT OnMouseEvent( UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled); LRESULT OnKeyEvent( @@ -304,6 +308,9 @@ class RenderWidgetHostViewWin void HandleLockedMouseEvent(UINT message, WPARAM wparam, LPARAM lparam); + LRESULT OnDocumentFeed(RECONVERTSTRING* reconv); + LRESULT OnReconvertString(RECONVERTSTRING* reconv); + // The associated Model. While |this| is being Destroyed, // |render_widget_host_| is NULL and the Windows message loop is run one last // time. Message handlers must check for a NULL |render_widget_host_|. @@ -411,6 +418,8 @@ class RenderWidgetHostViewWin // back, we regard the mouse movement as (0, 0). bool ignore_mouse_movement_; + ui::Range composition_range_; + DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewWin); }; |