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 "ui/base/win/ime_input.h" | 5 #include "ui/base/win/ime_input.h" |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/string16.h" | 9 #include "base/string16.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 | 116 |
117 } // namespace | 117 } // namespace |
118 | 118 |
119 namespace ui { | 119 namespace ui { |
120 | 120 |
121 ImeInput::ImeInput() | 121 ImeInput::ImeInput() |
122 : ime_status_(false), | 122 : ime_status_(false), |
123 input_language_id_(LANG_USER_DEFAULT), | 123 input_language_id_(LANG_USER_DEFAULT), |
124 is_composing_(false), | 124 is_composing_(false), |
125 system_caret_(false), | 125 system_caret_(false), |
126 caret_rect_(-1, -1, 0, 0) { | 126 caret_rect_(-1, -1, 0, 0), |
| 127 use_composition_window_(false) { |
127 } | 128 } |
128 | 129 |
129 ImeInput::~ImeInput() { | 130 ImeInput::~ImeInput() { |
130 } | 131 } |
131 | 132 |
132 bool ImeInput::SetInputLanguage() { | 133 bool ImeInput::SetInputLanguage() { |
133 // Retrieve the current keyboard layout from Windows and determine whether | 134 // Retrieve the current keyboard layout from Windows and determine whether |
134 // or not the current input context has IMEs. | 135 // or not the current input context has IMEs. |
135 // Also save its input language for language-specific operations required | 136 // Also save its input language for language-specific operations required |
136 // while composing a text. | 137 // while composing a text. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 // Destroy the system caret if we have created for this IME input context. | 184 // Destroy the system caret if we have created for this IME input context. |
184 if (system_caret_) { | 185 if (system_caret_) { |
185 ::DestroyCaret(); | 186 ::DestroyCaret(); |
186 system_caret_ = false; | 187 system_caret_ = false; |
187 } | 188 } |
188 } | 189 } |
189 | 190 |
190 void ImeInput::MoveImeWindow(HWND window_handle, HIMC imm_context) { | 191 void ImeInput::MoveImeWindow(HWND window_handle, HIMC imm_context) { |
191 int x = caret_rect_.x(); | 192 int x = caret_rect_.x(); |
192 int y = caret_rect_.y(); | 193 int y = caret_rect_.y(); |
| 194 |
193 const int kCaretMargin = 1; | 195 const int kCaretMargin = 1; |
194 if (PRIMARYLANGID(input_language_id_) == LANG_CHINESE) { | 196 if (!use_composition_window_ && |
| 197 PRIMARYLANGID(input_language_id_) == LANG_CHINESE) { |
195 // As written in a comment in ImeInput::CreateImeWindow(), | 198 // As written in a comment in ImeInput::CreateImeWindow(), |
196 // Chinese IMEs ignore function calls to ::ImmSetCandidateWindow() | 199 // Chinese IMEs ignore function calls to ::ImmSetCandidateWindow() |
197 // when a user disables TSF (Text Service Framework) and CUAS (Cicero | 200 // when a user disables TSF (Text Service Framework) and CUAS (Cicero |
198 // Unaware Application Support). | 201 // Unaware Application Support). |
199 // On the other hand, when a user enables TSF and CUAS, Chinese IMEs | 202 // On the other hand, when a user enables TSF and CUAS, Chinese IMEs |
200 // ignore the position of the current system caret and uses the | 203 // ignore the position of the current system caret and uses the |
201 // parameters given to ::ImmSetCandidateWindow() with its 'dwStyle' | 204 // parameters given to ::ImmSetCandidateWindow() with its 'dwStyle' |
202 // parameter CFS_CANDIDATEPOS. | 205 // parameter CFS_CANDIDATEPOS. |
203 // Therefore, we do not only call ::ImmSetCandidateWindow() but also | 206 // Therefore, we do not only call ::ImmSetCandidateWindow() but also |
204 // set the positions of the temporary system caret if it exists. | 207 // set the positions of the temporary system caret if it exists. |
205 CANDIDATEFORM candidate_position = {0, CFS_CANDIDATEPOS, {x, y}, | 208 CANDIDATEFORM candidate_position = {0, CFS_CANDIDATEPOS, {x, y}, |
206 {0, 0, 0, 0}}; | 209 {0, 0, 0, 0}}; |
207 ::ImmSetCandidateWindow(imm_context, &candidate_position); | 210 ::ImmSetCandidateWindow(imm_context, &candidate_position); |
208 } | 211 } |
209 if (system_caret_) { | 212 if (system_caret_) { |
210 switch (PRIMARYLANGID(input_language_id_)) { | 213 switch (PRIMARYLANGID(input_language_id_)) { |
211 case LANG_JAPANESE: | 214 case LANG_JAPANESE: |
212 ::SetCaretPos(x, y + caret_rect_.height()); | 215 ::SetCaretPos(x, y + caret_rect_.height()); |
213 break; | 216 break; |
214 default: | 217 default: |
215 ::SetCaretPos(x, y); | 218 ::SetCaretPos(x, y); |
216 break; | 219 break; |
217 } | 220 } |
218 } | 221 } |
| 222 if (use_composition_window_) { |
| 223 // Moves the composition text window. |
| 224 COMPOSITIONFORM cf = {CFS_POINT, {x, y}}; |
| 225 ::ImmSetCompositionWindow(imm_context, &cf); |
| 226 // Don't need to set the position of candidate window. |
| 227 return; |
| 228 } |
| 229 |
219 if (PRIMARYLANGID(input_language_id_) == LANG_KOREAN) { | 230 if (PRIMARYLANGID(input_language_id_) == LANG_KOREAN) { |
220 // Chinese IMEs and Japanese IMEs require the upper-left corner of | 231 // Chinese IMEs and Japanese IMEs require the upper-left corner of |
221 // the caret to move the position of their candidate windows. | 232 // the caret to move the position of their candidate windows. |
222 // On the other hand, Korean IMEs require the lower-left corner of the | 233 // On the other hand, Korean IMEs require the lower-left corner of the |
223 // caret to move their candidate windows. | 234 // caret to move their candidate windows. |
224 y += kCaretMargin; | 235 y += kCaretMargin; |
225 } | 236 } |
226 // Japanese IMEs and Korean IMEs also use the rectangle given to | 237 // Japanese IMEs and Korean IMEs also use the rectangle given to |
227 // ::ImmSetCandidateWindow() with its 'dwStyle' parameter CFS_EXCLUDE | 238 // ::ImmSetCandidateWindow() with its 'dwStyle' parameter CFS_EXCLUDE |
228 // to move their candidate windows when a user disables TSF and CUAS. | 239 // to move their candidate windows when a user disables TSF and CUAS. |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 caret_rect_ = caret_rect; | 450 caret_rect_ = caret_rect; |
440 // Move the IME windows. | 451 // Move the IME windows. |
441 HIMC imm_context = ::ImmGetContext(window_handle); | 452 HIMC imm_context = ::ImmGetContext(window_handle); |
442 if (imm_context) { | 453 if (imm_context) { |
443 MoveImeWindow(window_handle, imm_context); | 454 MoveImeWindow(window_handle, imm_context); |
444 ::ImmReleaseContext(window_handle, imm_context); | 455 ::ImmReleaseContext(window_handle, imm_context); |
445 } | 456 } |
446 } | 457 } |
447 } | 458 } |
448 | 459 |
| 460 void ImeInput::SetUseCompositionWindow(bool use_composition_window) { |
| 461 use_composition_window_ = use_composition_window; |
| 462 } |
| 463 |
449 std::string ImeInput::GetInputLanguageName() const { | 464 std::string ImeInput::GetInputLanguageName() const { |
450 const LCID locale_id = MAKELCID(input_language_id_, SORT_DEFAULT); | 465 const LCID locale_id = MAKELCID(input_language_id_, SORT_DEFAULT); |
451 // max size for LOCALE_SISO639LANGNAME and LOCALE_SISO3166CTRYNAME is 9. | 466 // max size for LOCALE_SISO639LANGNAME and LOCALE_SISO3166CTRYNAME is 9. |
452 wchar_t buffer[9]; | 467 wchar_t buffer[9]; |
453 | 468 |
454 // Get language id. | 469 // Get language id. |
455 int length = ::GetLocaleInfo(locale_id, LOCALE_SISO639LANGNAME, &buffer[0], | 470 int length = ::GetLocaleInfo(locale_id, LOCALE_SISO639LANGNAME, &buffer[0], |
456 arraysize(buffer)); | 471 arraysize(buffer)); |
457 if (length <= 1) | 472 if (length <= 1) |
458 return std::string(); | 473 return std::string(); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
551 keystate[VK_RCONTROL] = 0; | 566 keystate[VK_RCONTROL] = 0; |
552 keystate[VK_LCONTROL] = 0; | 567 keystate[VK_LCONTROL] = 0; |
553 for (int i = 0; i <= VK_PACKET; ++i) { | 568 for (int i = 0; i <= VK_PACKET; ++i) { |
554 if (keystate[i] & kKeyDownMask) | 569 if (keystate[i] & kKeyDownMask) |
555 return false; | 570 return false; |
556 } | 571 } |
557 return true; | 572 return true; |
558 } | 573 } |
559 | 574 |
560 } // namespace ui | 575 } // namespace ui |
OLD | NEW |