OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "chrome/browser/chromeos/input_method/input_method_engine.h" | 5 #include "chrome/browser/chromeos/input_method/input_method_engine.h" |
6 | 6 |
7 #define XK_MISCELLANY | |
8 #include <X11/keysymdef.h> | |
9 #include <X11/X.h> | |
10 #include <X11/Xlib.h> | |
11 #include <X11/Xutil.h> | |
12 #undef FocusIn | 7 #undef FocusIn |
13 #undef FocusOut | 8 #undef FocusOut |
14 #undef RootWindow | 9 #undef RootWindow |
15 #include <map> | 10 #include <map> |
16 | 11 |
17 #include "ash/ime/input_method_menu_item.h" | 12 #include "ash/ime/input_method_menu_item.h" |
18 #include "ash/ime/input_method_menu_manager.h" | 13 #include "ash/ime/input_method_menu_manager.h" |
19 #include "ash/shell.h" | 14 #include "ash/shell.h" |
20 #include "base/logging.h" | 15 #include "base/logging.h" |
21 #include "base/memory/scoped_ptr.h" | 16 #include "base/memory/scoped_ptr.h" |
22 #include "base/metrics/histogram.h" | 17 #include "base/metrics/histogram.h" |
23 #include "base/strings/string_number_conversions.h" | 18 #include "base/strings/string_number_conversions.h" |
24 #include "base/strings/string_util.h" | 19 #include "base/strings/string_util.h" |
25 #include "base/strings/stringprintf.h" | 20 #include "base/strings/stringprintf.h" |
26 #include "base/strings/utf_string_conversions.h" | 21 #include "base/strings/utf_string_conversions.h" |
27 #include "chromeos/ime/component_extension_ime_manager.h" | 22 #include "chromeos/ime/component_extension_ime_manager.h" |
28 #include "chromeos/ime/composition_text.h" | 23 #include "chromeos/ime/composition_text.h" |
29 #include "chromeos/ime/extension_ime_util.h" | 24 #include "chromeos/ime/extension_ime_util.h" |
30 #include "chromeos/ime/input_method_manager.h" | 25 #include "chromeos/ime/input_method_manager.h" |
31 #include "ui/aura/window.h" | 26 #include "ui/aura/window.h" |
32 #include "ui/aura/window_tree_host.h" | 27 #include "ui/aura/window_tree_host.h" |
33 #include "ui/base/ime/candidate_window.h" | 28 #include "ui/base/ime/candidate_window.h" |
34 #include "ui/base/ime/chromeos/ime_keymap.h" | 29 #include "ui/base/ime/chromeos/ime_keymap.h" |
35 #include "ui/events/event.h" | 30 #include "ui/events/event.h" |
36 #include "ui/events/event_processor.h" | 31 #include "ui/events/event_processor.h" |
37 #include "ui/events/keycodes/dom4/keycode_converter.h" | |
38 #include "ui/events/keycodes/keyboard_code_conversion_x.h" | |
39 #include "ui/keyboard/keyboard_controller.h" | 32 #include "ui/keyboard/keyboard_controller.h" |
40 #include "ui/keyboard/keyboard_util.h" | 33 #include "ui/keyboard/keyboard_util.h" |
41 | 34 |
42 namespace chromeos { | 35 namespace chromeos { |
43 const char* kErrorNotActive = "IME is not active"; | 36 const char* kErrorNotActive = "IME is not active"; |
44 const char* kErrorWrongContext = "Context is not active"; | 37 const char* kErrorWrongContext = "Context is not active"; |
45 const char* kCandidateNotFound = "Candidate not found"; | 38 const char* kCandidateNotFound = "Candidate not found"; |
46 | 39 |
47 namespace { | 40 namespace { |
48 | 41 |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 } | 252 } |
260 | 253 |
261 ui::EventProcessor* dispatcher = | 254 ui::EventProcessor* dispatcher = |
262 ash::Shell::GetPrimaryRootWindow()->GetHost()->event_processor(); | 255 ash::Shell::GetPrimaryRootWindow()->GetHost()->event_processor(); |
263 | 256 |
264 for (size_t i = 0; i < events.size(); ++i) { | 257 for (size_t i = 0; i < events.size(); ++i) { |
265 const KeyboardEvent& event = events[i]; | 258 const KeyboardEvent& event = events[i]; |
266 const ui::EventType type = | 259 const ui::EventType type = |
267 (event.type == "keyup") ? ui::ET_KEY_RELEASED : ui::ET_KEY_PRESSED; | 260 (event.type == "keyup") ? ui::ET_KEY_RELEASED : ui::ET_KEY_PRESSED; |
268 | 261 |
269 // KeyboardCodeFromXKyeSym assumes US keyboard layout. | |
270 ui::KeycodeConverter* conv = ui::KeycodeConverter::GetInstance(); | |
271 DCHECK(conv); | |
272 | |
273 // DOM code (KeyA) -> XKB -> XKeySym (XK_A) -> KeyboardCode (VKEY_A) | |
274 const uint16 native_keycode = | |
275 conv->CodeToNativeKeycode(event.code.c_str()); | |
276 const uint xkeysym = ui::DefaultXKeysymFromHardwareKeycode(native_keycode); | |
277 const ui::KeyboardCode key_code = ui::KeyboardCodeFromXKeysym(xkeysym); | |
278 | |
279 const std::string code = event.code; | |
280 int flags = ui::EF_NONE; | 262 int flags = ui::EF_NONE; |
281 flags |= event.alt_key ? ui::EF_ALT_DOWN : ui::EF_NONE; | 263 flags |= event.alt_key ? ui::EF_ALT_DOWN : ui::EF_NONE; |
282 flags |= event.ctrl_key ? ui::EF_CONTROL_DOWN : ui::EF_NONE; | 264 flags |= event.ctrl_key ? ui::EF_CONTROL_DOWN : ui::EF_NONE; |
283 flags |= event.shift_key ? ui::EF_SHIFT_DOWN : ui::EF_NONE; | 265 flags |= event.shift_key ? ui::EF_SHIFT_DOWN : ui::EF_NONE; |
284 flags |= event.caps_lock ? ui::EF_CAPS_LOCK_DOWN : ui::EF_NONE; | 266 flags |= event.caps_lock ? ui::EF_CAPS_LOCK_DOWN : ui::EF_NONE; |
285 | 267 |
286 ui::KeyEvent ui_event(type, key_code, code, flags, false /* is_char */); | 268 ui::KeyEvent ui_event(type, |
| 269 ui::FromCodeToKeyboardCode(event.code), |
| 270 event.code, |
| 271 flags, |
| 272 false /* is_char */); |
| 273 if (!event.key.empty()) |
| 274 ui_event.set_character(base::UTF8ToUTF16(event.key)[0]); |
287 base::AutoReset<const ui::KeyEvent*> reset_sent_key(&sent_key_event_, | 275 base::AutoReset<const ui::KeyEvent*> reset_sent_key(&sent_key_event_, |
288 &ui_event); | 276 &ui_event); |
289 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&ui_event); | 277 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&ui_event); |
290 if (details.dispatcher_destroyed) | 278 if (details.dispatcher_destroyed) |
291 break; | 279 break; |
292 } | 280 } |
293 return true; | 281 return true; |
294 } | 282 } |
295 | 283 |
296 const InputMethodEngine::CandidateWindowProperty& | 284 const InputMethodEngine::CandidateWindowProperty& |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 | 565 |
578 void InputMethodEngine::PropertyActivate(const std::string& property_name) { | 566 void InputMethodEngine::PropertyActivate(const std::string& property_name) { |
579 observer_->OnMenuItemActivated(engine_id_, property_name); | 567 observer_->OnMenuItemActivated(engine_id_, property_name); |
580 } | 568 } |
581 | 569 |
582 void InputMethodEngine::Reset() { | 570 void InputMethodEngine::Reset() { |
583 observer_->OnReset(engine_id_); | 571 observer_->OnReset(engine_id_); |
584 } | 572 } |
585 | 573 |
586 namespace { | 574 namespace { |
| 575 |
587 void GetExtensionKeyboardEventFromKeyEvent( | 576 void GetExtensionKeyboardEventFromKeyEvent( |
588 const ui::KeyEvent& event, | 577 const ui::KeyEvent& event, |
589 InputMethodEngine::KeyboardEvent* ext_event) { | 578 InputMethodEngine::KeyboardEvent* ext_event) { |
590 DCHECK(event.type() == ui::ET_KEY_RELEASED || | 579 DCHECK(event.type() == ui::ET_KEY_RELEASED || |
591 event.type() == ui::ET_KEY_PRESSED); | 580 event.type() == ui::ET_KEY_PRESSED); |
592 DCHECK(ext_event); | 581 DCHECK(ext_event); |
593 ext_event->type = (event.type() == ui::ET_KEY_RELEASED) ? "keyup" : "keydown"; | 582 ext_event->type = (event.type() == ui::ET_KEY_RELEASED) ? "keyup" : "keydown"; |
594 | 583 |
595 ext_event->code = event.code(); | 584 ext_event->code = event.code(); |
596 ext_event->alt_key = event.IsAltDown(); | 585 ext_event->alt_key = event.IsAltDown(); |
597 ext_event->ctrl_key = event.IsControlDown(); | 586 ext_event->ctrl_key = event.IsControlDown(); |
598 ext_event->shift_key = event.IsShiftDown(); | 587 ext_event->shift_key = event.IsShiftDown(); |
599 ext_event->caps_lock = event.IsCapsLockDown(); | 588 ext_event->caps_lock = event.IsCapsLockDown(); |
| 589 ext_event->key = UTF16ToUTF8(base::string16(1, event.GetCharacter())); |
| 590 } |
600 | 591 |
601 uint32 x11_keysym = 0; | |
602 if (event.HasNativeEvent()) { | |
603 const base::NativeEvent& native_event = event.native_event(); | |
604 DCHECK(native_event); | |
605 | |
606 XKeyEvent* x_key = &(static_cast<XEvent*>(native_event)->xkey); | |
607 KeySym keysym = NoSymbol; | |
608 ::XLookupString(x_key, NULL, 0, &keysym, NULL); | |
609 x11_keysym = keysym; | |
610 } else { | |
611 // Convert ui::KeyEvent.key_code to DOM UIEvent key. | |
612 // XKeysymForWindowsKeyCode converts key_code to XKeySym, but it | |
613 // assumes US layout and does not care about CapLock state. | |
614 // | |
615 // TODO(komatsu): Support CapsLock states. | |
616 // TODO(komatsu): Support non-us keyboard layouts. | |
617 x11_keysym = ui::XKeysymForWindowsKeyCode(event.key_code(), | |
618 event.IsShiftDown()); | |
619 } | |
620 ext_event->key = ui::FromXKeycodeToKeyValue(x11_keysym); | |
621 } | |
622 } // namespace | 592 } // namespace |
623 | 593 |
624 void InputMethodEngine::ProcessKeyEvent( | 594 void InputMethodEngine::ProcessKeyEvent( |
625 const ui::KeyEvent& key_event, | 595 const ui::KeyEvent& key_event, |
626 const KeyEventDoneCallback& callback) { | 596 const KeyEventDoneCallback& callback) { |
627 | 597 |
628 KeyEventDoneCallback *handler = new KeyEventDoneCallback(); | 598 KeyEventDoneCallback *handler = new KeyEventDoneCallback(); |
629 *handler = callback; | 599 *handler = callback; |
630 | 600 |
631 KeyboardEvent ext_event; | 601 KeyboardEvent ext_event; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
699 // TODO(nona): Implement it. | 669 // TODO(nona): Implement it. |
700 break; | 670 break; |
701 } | 671 } |
702 } | 672 } |
703 } | 673 } |
704 | 674 |
705 // TODO(nona): Support item.children. | 675 // TODO(nona): Support item.children. |
706 } | 676 } |
707 | 677 |
708 } // namespace chromeos | 678 } // namespace chromeos |
OLD | NEW |