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

Side by Side Diff: views/ime/input_method_win.cc

Issue 8294026: Support IMM32 reconversion on Windows (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Fix review issues Created 9 years, 1 month 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « views/ime/input_method_win.h ('k') | views/ime/text_input_client.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "ui/base/keycodes/keyboard_codes.h" 10 #include "ui/base/keycodes/keyboard_codes.h"
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 break; 108 break;
109 case WM_IME_STARTCOMPOSITION: 109 case WM_IME_STARTCOMPOSITION:
110 result = OnImeStartComposition(message, w_param, l_param, handled); 110 result = OnImeStartComposition(message, w_param, l_param, handled);
111 break; 111 break;
112 case WM_IME_COMPOSITION: 112 case WM_IME_COMPOSITION:
113 result = OnImeComposition(message, w_param, l_param, handled); 113 result = OnImeComposition(message, w_param, l_param, handled);
114 break; 114 break;
115 case WM_IME_ENDCOMPOSITION: 115 case WM_IME_ENDCOMPOSITION:
116 result = OnImeEndComposition(message, w_param, l_param, handled); 116 result = OnImeEndComposition(message, w_param, l_param, handled);
117 break; 117 break;
118 case WM_IME_REQUEST:
119 result = OnImeRequest(message, w_param, l_param, handled);
120 break;
118 case WM_CHAR: 121 case WM_CHAR:
119 case WM_SYSCHAR: 122 case WM_SYSCHAR:
120 result = OnChar(message, w_param, l_param, handled); 123 result = OnChar(message, w_param, l_param, handled);
121 break; 124 break;
122 case WM_DEADCHAR: 125 case WM_DEADCHAR:
123 case WM_SYSDEADCHAR: 126 case WM_SYSDEADCHAR:
124 result = OnDeadChar(message, w_param, l_param, handled); 127 result = OnDeadChar(message, w_param, l_param, handled);
125 break; 128 break;
126 default: 129 default:
127 NOTREACHED() << "Unknown IME message:" << message; 130 NOTREACHED() << "Unknown IME message:" << message;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 return 0; 215 return 0;
213 216
214 if (GetTextInputClient()->HasCompositionText()) 217 if (GetTextInputClient()->HasCompositionText())
215 GetTextInputClient()->ClearCompositionText(); 218 GetTextInputClient()->ClearCompositionText();
216 219
217 ime_input_.ResetComposition(hwnd()); 220 ime_input_.ResetComposition(hwnd());
218 ime_input_.DestroyImeWindow(hwnd()); 221 ime_input_.DestroyImeWindow(hwnd());
219 return 0; 222 return 0;
220 } 223 }
221 224
225 LRESULT InputMethodWin::OnImeRequest(
226 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) {
227 *handled = FALSE;
228
229 // Should not receive WM_IME_REQUEST message, if IME is disabled.
230 ui::TextInputType type = GetTextInputType();
James Su 2011/10/26 18:41:57 nit: const ui::TextInputType
231 if (type == ui::TEXT_INPUT_TYPE_NONE ||
232 type == ui::TEXT_INPUT_TYPE_PASSWORD) {
233 return 0;
234 }
235
236 switch (wparam) {
237 case IMR_RECONVERTSTRING:
238 *handled = TRUE;
239 return OnReconvertString(reinterpret_cast<RECONVERTSTRING*>(lparam));
240 case IMR_DOCUMENTFEED:
241 *handled = TRUE;
242 return OnDocumentFeed(reinterpret_cast<RECONVERTSTRING*>(lparam));
243 default:
244 return 0;
245 }
246 }
247
222 LRESULT InputMethodWin::OnChar( 248 LRESULT InputMethodWin::OnChar(
223 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) { 249 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) {
224 *handled = TRUE; 250 *handled = TRUE;
225 251
226 // We need to send character events to the focused text input client event if 252 // 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. 253 // its text input type is ui::TEXT_INPUT_TYPE_NONE.
228 if (!GetTextInputClient()) 254 if (!GetTextInputClient())
229 return 0; 255 return 0;
230 256
231 int flags = 0; 257 int flags = 0;
(...skipping 15 matching lines...) Expand all
247 // what dead key was pressed. 273 // what dead key was pressed.
248 ui::CompositionText composition; 274 ui::CompositionText composition;
249 composition.text.assign(1, static_cast<char16>(wparam)); 275 composition.text.assign(1, static_cast<char16>(wparam));
250 composition.selection = ui::Range(0, 1); 276 composition.selection = ui::Range(0, 1);
251 composition.underlines.push_back( 277 composition.underlines.push_back(
252 ui::CompositionUnderline(0, 1, SK_ColorBLACK, false)); 278 ui::CompositionUnderline(0, 1, SK_ColorBLACK, false));
253 GetTextInputClient()->SetCompositionText(composition); 279 GetTextInputClient()->SetCompositionText(composition);
254 return 0; 280 return 0;
255 } 281 }
256 282
283 LRESULT InputMethodWin::OnDocumentFeed(RECONVERTSTRING *reconv) {
284 TextInputClient* client = GetTextInputClient();
285 if (!client)
286 return 0;
287
288 ui::Range text_range;
289 if (!client->GetTextRange(&text_range) || text_range.is_empty())
290 return 0;
291
292 ui::Range target_range;
293 do {
294 if (client->HasCompositionText() &&
295 client->GetCompositionTextRange(&target_range) &&
296 !target_range.is_empty()) {
297 break;
298 }
299 if (client->GetSelectionRange(&target_range))
300 break;
301 return 0;
302 } while (0);
303
304 if (!text_range.Contains(target_range))
305 return 0;
306
307 size_t len = text_range.length();
308 size_t need_size = sizeof(RECONVERTSTRING) + len * sizeof(WCHAR);
309
310 if (!reconv)
311 return need_size;
312
313 if (reconv->dwSize < need_size)
314 return 0;
315
316 string16 text;
317 ui::Range actual_range;
318 if (!GetTextInputClient()->GetTextFromRange(
319 text_range, &text, &actual_range)) {
320 return 0;
321 }
322
323 DCHECK(text_range == actual_range);
324
325 reconv->dwVersion = 0;
326 reconv->dwStrLen = len;
327 reconv->dwStrOffset = sizeof(RECONVERTSTRING);
328 reconv->dwCompStrLen =
329 client->HasCompositionText() ? reconv->dwTargetStrOffset : 0;
330 reconv->dwCompStrOffset =
331 (target_range.GetMin() - text_range.start()) * sizeof(WCHAR);
332 reconv->dwTargetStrLen = target_range.length();
333 reconv->dwTargetStrOffset = reconv->dwCompStrOffset;
334
335 memcpy((char*)reconv + sizeof(RECONVERTSTRING),
336 text.c_str(), len * sizeof(WCHAR));
337
338 return need_size;
339 }
340
341 LRESULT InputMethodWin::OnReconvertString(RECONVERTSTRING *reconv) {
342 TextInputClient* client = GetTextInputClient();
343 if (!client)
344 return 0;
345
346 // If there is a composition string already, we don't allow reconversion.
347 if (client->HasCompositionText())
348 return 0;
349
350 ui::Range text_range;
351 if (!client->GetTextRange(&text_range) || text_range.is_empty())
352 return 0;
353
354 ui::Range selection_range;
355 if (!client->GetSelectionRange(&selection_range) ||
356 selection_range.is_empty()) {
357 return 0;
358 }
359
360 if (!text_range.Contains(selection_range))
361 return 0;
362
363 size_t len = text_range.length();
James Su 2011/10/26 18:41:57 It's better not to return all text content, becaus
364 size_t need_size = sizeof(RECONVERTSTRING) + len * sizeof(WCHAR);
365
366 if (!reconv)
367 return need_size;
368
369 if (reconv->dwSize < need_size)
370 return 0;
371
372 string16 text;
373 ui::Range actual_range;
374 if (!GetTextInputClient()->GetTextFromRange(
375 text_range, &text, &actual_range))
376 return 0;
377
378 reconv->dwVersion = 0;
379 reconv->dwStrLen = len;
380 reconv->dwStrOffset = sizeof(RECONVERTSTRING);
381 reconv->dwCompStrLen = selection_range.length();
382 reconv->dwCompStrOffset =
383 (selection_range.GetMin() - text_range.start()) * sizeof(WCHAR);
384 reconv->dwTargetStrLen = reconv->dwCompStrLen;
385 reconv->dwTargetStrOffset = reconv->dwCompStrOffset;
386 memcpy(reinterpret_cast<char*>(reconv) + sizeof(RECONVERTSTRING),
387 text.c_str(), len * sizeof(WCHAR));
388
389 return need_size;
390 }
391
257 void InputMethodWin::ConfirmCompositionText() { 392 void InputMethodWin::ConfirmCompositionText() {
258 if (!IsTextInputTypeNone()) { 393 if (!IsTextInputTypeNone()) {
259 ime_input_.CleanupComposition(hwnd()); 394 ime_input_.CleanupComposition(hwnd());
260 // Though above line should confirm the client's composition text by sending 395 // Though above line should confirm the client's composition text by sending
261 // a result text to us, in case the input method and the client are in 396 // a result text to us, in case the input method and the client are in
262 // inconsistent states, we check the client's composition state again. 397 // inconsistent states, we check the client's composition state again.
263 if (GetTextInputClient()->HasCompositionText()) 398 if (GetTextInputClient()->HasCompositionText())
264 GetTextInputClient()->ConfirmCompositionText(); 399 GetTextInputClient()->ConfirmCompositionText();
265 } 400 }
266 } 401 }
267 402
268 void InputMethodWin::UpdateIMEState() { 403 void InputMethodWin::UpdateIMEState() {
269 // Use switch here in case we are going to add more text input types. 404 // Use switch here in case we are going to add more text input types.
270 // We disable input method in password field. 405 // We disable input method in password field.
271 switch (GetTextInputType()) { 406 switch (GetTextInputType()) {
272 case ui::TEXT_INPUT_TYPE_NONE: 407 case ui::TEXT_INPUT_TYPE_NONE:
273 case ui::TEXT_INPUT_TYPE_PASSWORD: 408 case ui::TEXT_INPUT_TYPE_PASSWORD:
274 ime_input_.DisableIME(hwnd()); 409 ime_input_.DisableIME(hwnd());
275 break; 410 break;
276 default: 411 default:
277 ime_input_.EnableIME(hwnd()); 412 ime_input_.EnableIME(hwnd());
278 break; 413 break;
279 } 414 }
280 } 415 }
281 416
282 } // namespace views 417 } // namespace views
OLDNEW
« no previous file with comments | « views/ime/input_method_win.h ('k') | views/ime/text_input_client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698