OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "views/ime/input_method_win.h" | 5 #include "views/ime/input_method_win.h" |
6 | 6 |
| 7 #include <algorithm> |
| 8 |
7 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
8 #include "base/logging.h" | 10 #include "base/logging.h" |
9 #include "base/string_util.h" | 11 #include "base/string_util.h" |
10 #include "ui/base/keycodes/keyboard_codes.h" | 12 #include "ui/base/keycodes/keyboard_codes.h" |
11 #include "views/events/event.h" | 13 #include "views/events/event.h" |
12 | 14 |
13 namespace views { | 15 namespace views { |
14 | 16 |
15 InputMethodWin::InputMethodWin(internal::InputMethodDelegate* delegate) | 17 InputMethodWin::InputMethodWin(internal::InputMethodDelegate* delegate) |
16 : active_(false), | 18 : active_(false), |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 break; | 110 break; |
109 case WM_IME_STARTCOMPOSITION: | 111 case WM_IME_STARTCOMPOSITION: |
110 result = OnImeStartComposition(message, w_param, l_param, handled); | 112 result = OnImeStartComposition(message, w_param, l_param, handled); |
111 break; | 113 break; |
112 case WM_IME_COMPOSITION: | 114 case WM_IME_COMPOSITION: |
113 result = OnImeComposition(message, w_param, l_param, handled); | 115 result = OnImeComposition(message, w_param, l_param, handled); |
114 break; | 116 break; |
115 case WM_IME_ENDCOMPOSITION: | 117 case WM_IME_ENDCOMPOSITION: |
116 result = OnImeEndComposition(message, w_param, l_param, handled); | 118 result = OnImeEndComposition(message, w_param, l_param, handled); |
117 break; | 119 break; |
| 120 case WM_IME_REQUEST: |
| 121 result = OnImeRequest(message, w_param, l_param, handled); |
| 122 break; |
118 case WM_CHAR: | 123 case WM_CHAR: |
119 case WM_SYSCHAR: | 124 case WM_SYSCHAR: |
120 result = OnChar(message, w_param, l_param, handled); | 125 result = OnChar(message, w_param, l_param, handled); |
121 break; | 126 break; |
122 case WM_DEADCHAR: | 127 case WM_DEADCHAR: |
123 case WM_SYSDEADCHAR: | 128 case WM_SYSDEADCHAR: |
124 result = OnDeadChar(message, w_param, l_param, handled); | 129 result = OnDeadChar(message, w_param, l_param, handled); |
125 break; | 130 break; |
126 default: | 131 default: |
127 NOTREACHED() << "Unknown IME message:" << message; | 132 NOTREACHED() << "Unknown IME message:" << message; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 return 0; | 217 return 0; |
213 | 218 |
214 if (GetTextInputClient()->HasCompositionText()) | 219 if (GetTextInputClient()->HasCompositionText()) |
215 GetTextInputClient()->ClearCompositionText(); | 220 GetTextInputClient()->ClearCompositionText(); |
216 | 221 |
217 ime_input_.ResetComposition(hwnd()); | 222 ime_input_.ResetComposition(hwnd()); |
218 ime_input_.DestroyImeWindow(hwnd()); | 223 ime_input_.DestroyImeWindow(hwnd()); |
219 return 0; | 224 return 0; |
220 } | 225 } |
221 | 226 |
| 227 LRESULT InputMethodWin::OnReconvertString(RECONVERTSTRING *reconv) { |
| 228 TextInputClient* client = GetTextInputClient(); |
| 229 if (!client) |
| 230 return 0; |
| 231 |
| 232 // If there is a composition string already, we don't allow reconversion. |
| 233 if (client->HasCompositionText()) |
| 234 return 0; |
| 235 |
| 236 ui::Range selection_range; |
| 237 if (!client->GetSelectionRange(&selection_range) || |
| 238 selection_range.is_empty()) { |
| 239 return 0; |
| 240 } |
| 241 |
| 242 size_t len = selection_range.length(); |
| 243 size_t need_size = sizeof(RECONVERTSTRING) + len * sizeof(WCHAR); |
| 244 |
| 245 if (!reconv) |
| 246 return need_size; |
| 247 |
| 248 if (reconv->dwSize < need_size) |
| 249 return 0; |
| 250 |
| 251 string16 text; |
| 252 ui::Range actual_range; |
| 253 if (!GetTextInputClient()->GetTextFromRange( |
| 254 selection_range, &text, &actual_range)) |
| 255 return 0; |
| 256 |
| 257 reconv->dwVersion = 0; |
| 258 reconv->dwStrLen = len; |
| 259 reconv->dwStrOffset = sizeof(RECONVERTSTRING); |
| 260 reconv->dwCompStrLen = len; |
| 261 reconv->dwCompStrOffset = 0; |
| 262 reconv->dwTargetStrLen = len; |
| 263 reconv->dwTargetStrOffset = 0; |
| 264 memcpy(reinterpret_cast<char*>(reconv) + sizeof(RECONVERTSTRING), |
| 265 text.c_str(), len * sizeof(WCHAR)); |
| 266 |
| 267 return need_size; |
| 268 } |
| 269 |
| 270 LRESULT InputMethodWin::OnDocumentFeed(RECONVERTSTRING *reconv) { |
| 271 TextInputClient* client = GetTextInputClient(); |
| 272 if (!client) |
| 273 return 0; |
| 274 |
| 275 ui::Range text_range; |
| 276 if (!client->GetTextRange(&text_range) || text_range.is_empty()) |
| 277 return 0; |
| 278 |
| 279 ui::Range target_range; |
| 280 do { |
| 281 if (client->HasCompositionText() && |
| 282 client->GetCompositionTextRange(&target_range) && |
| 283 !target_range.is_empty()) { |
| 284 break; |
| 285 } |
| 286 if (client->GetSelectionRange(&target_range)) |
| 287 break; |
| 288 return 0; |
| 289 } while (0); |
| 290 |
| 291 if (!text_range.Contains(target_range)) |
| 292 return 0; |
| 293 |
| 294 size_t len = text_range.length(); |
| 295 size_t need_size = sizeof(RECONVERTSTRING) + len * sizeof(WCHAR); |
| 296 |
| 297 if (!reconv) |
| 298 return need_size; |
| 299 |
| 300 if (reconv->dwSize < need_size) |
| 301 return 0; |
| 302 |
| 303 string16 text; |
| 304 ui::Range actual_range; |
| 305 if (!GetTextInputClient()->GetTextFromRange( |
| 306 text_range, &text, &actual_range)) { |
| 307 return 0; |
| 308 } |
| 309 |
| 310 DCHECK(text_range == actual_range); |
| 311 |
| 312 reconv->dwVersion = 0; |
| 313 reconv->dwStrLen = len; |
| 314 reconv->dwStrOffset = sizeof(RECONVERTSTRING); |
| 315 reconv->dwCompStrLen = |
| 316 client->HasCompositionText() ? reconv->dwTargetStrOffset : 0; |
| 317 reconv->dwCompStrOffset = |
| 318 (target_range.GetMin() - text_range.start()) * sizeof(WCHAR); |
| 319 reconv->dwTargetStrLen = target_range.length(); |
| 320 reconv->dwTargetStrOffset = reconv->dwCompStrOffset; |
| 321 |
| 322 memcpy((char*)reconv + sizeof(RECONVERTSTRING), |
| 323 text.c_str(), len * sizeof(WCHAR)); |
| 324 |
| 325 return need_size; |
| 326 } |
| 327 |
| 328 LRESULT InputMethodWin::OnImeRequest( |
| 329 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) { |
| 330 *handled = FALSE; |
| 331 |
| 332 if (IsTextInputTypeNone()) |
| 333 return 0; |
| 334 |
| 335 switch (wparam) { |
| 336 case IMR_RECONVERTSTRING: |
| 337 *handled = TRUE; |
| 338 return OnReconvertString(reinterpret_cast<RECONVERTSTRING*>(lparam)); |
| 339 case IMR_DOCUMENTFEED: |
| 340 *handled = TRUE; |
| 341 return OnDocumentFeed(reinterpret_cast<RECONVERTSTRING*>(lparam)); |
| 342 default: |
| 343 return 0; |
| 344 } |
| 345 } |
| 346 |
222 LRESULT InputMethodWin::OnChar( | 347 LRESULT InputMethodWin::OnChar( |
223 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) { | 348 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) { |
224 *handled = TRUE; | 349 *handled = TRUE; |
225 | 350 |
226 // We need to send character events to the focused text input client event if | 351 // We need to send character events to the focused text input client event if |
227 // its text input type is ui::TEXT_INPUT_TYPE_NONE. | 352 // its text input type is ui::TEXT_INPUT_TYPE_NONE. |
228 if (!GetTextInputClient()) | 353 if (!GetTextInputClient()) |
229 return 0; | 354 return 0; |
230 | 355 |
231 int flags = 0; | 356 int flags = 0; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 case ui::TEXT_INPUT_TYPE_PASSWORD: | 398 case ui::TEXT_INPUT_TYPE_PASSWORD: |
274 ime_input_.DisableIME(hwnd()); | 399 ime_input_.DisableIME(hwnd()); |
275 break; | 400 break; |
276 default: | 401 default: |
277 ime_input_.EnableIME(hwnd()); | 402 ime_input_.EnableIME(hwnd()); |
278 break; | 403 break; |
279 } | 404 } |
280 } | 405 } |
281 | 406 |
282 } // namespace views | 407 } // namespace views |
OLD | NEW |