Chromium Code Reviews| Index: ui/keyboard/keyboard_util.cc |
| diff --git a/ui/keyboard/keyboard_util.cc b/ui/keyboard/keyboard_util.cc |
| index 076eacff109eccdc480903b38289cf1ff2d1386b..e14045ebc5512a0f16914bf3b64d9fd61f1ca684 100644 |
| --- a/ui/keyboard/keyboard_util.cc |
| +++ b/ui/keyboard/keyboard_util.cc |
| @@ -15,8 +15,67 @@ |
| #include "ui/aura/root_window.h" |
| #include "ui/base/ime/input_method.h" |
| #include "ui/base/ime/text_input_client.h" |
| +#include "ui/base/keycodes/keyboard_code_conversion.h" |
| #include "ui/keyboard/keyboard_switches.h" |
| +namespace { |
| + |
| +const char kKeyPressed[] ="keyPressed"; |
| +const char kKeyReleased[] = "keyReleased"; |
| + |
| +const int kMinKeyCode = ui::VKEY_BACK; |
| +const int kMaxKeyCode = ui::VKEY_OEM_CLEAR; |
| +const int kMaxKeyChar = 0x7f; |
| + |
| +static bool initialized = false; |
| +static int unshifted_character_map[kMaxKeyChar]; |
| +static int shifted_character_map[kMaxKeyChar]; |
| + |
| +// Initializes mapping of characters to keycodes. |
| +void InitCharacterMapping() { |
| + for (int i = kMinKeyCode; i <= kMaxKeyCode; i++) { |
| + uint16 ch = ui::GetCharacterFromKeyCode(static_cast<ui::KeyboardCode>(i), |
|
bshe
2013/07/25 15:33:05
nit: indent is off here.
kevers
2013/07/26 00:53:30
Fixed.
|
| + ui::EF_NONE); |
| + if (ch > 0 && ch < kMaxKeyChar) |
| + unshifted_character_map[ch] = i; |
| + ch = ui::GetCharacterFromKeyCode(static_cast<ui::KeyboardCode>(i), |
| + ui::EF_SHIFT_DOWN); |
| + if (ch > 0 && ch < kMaxKeyChar) |
| + shifted_character_map[ch] = i; |
| + } |
| + initialized = true; |
| +} |
| + |
| +// Creates a synthetic KeyEvent corresponding to a |char_code|. The KeyEvent |
| +// contains a keycode and modifier flags. The character code is also |
| +// explicitly set to enable key events for i18n characters not found on a |
| +// US-English keyboard. |
| +ui::KeyEvent CreateFabricatedKeyEvent(ui::EventType type, int char_code) { |
| + if (!initialized) |
| + InitCharacterMapping(); |
| + |
| + ui::KeyboardCode keyCode = ui::VKEY_UNKNOWN; |
| + int flags = ui::EF_NONE; |
| + if (char_code < kMaxKeyChar) { |
| + int unshifted = unshifted_character_map[char_code]; |
| + if (unshifted > 0) { |
| + keyCode = static_cast<ui::KeyboardCode>(unshifted); |
| + } else { |
| + int shifted = shifted_character_map[char_code]; |
| + if (shifted > 0) { |
| + keyCode = static_cast<ui::KeyboardCode>(shifted); |
| + flags = ui::EF_SHIFT_DOWN; |
| + } |
| + } |
| + } |
| + ui::KeyEvent event(type, keyCode, flags, false); |
| + event.set_character(char_code); |
| + event.set_unmodified_character(char_code); |
| + return event; |
| +} |
| + |
| +} // namespace |
| + |
| namespace keyboard { |
| bool IsKeyboardEnabled() { |
| @@ -30,7 +89,7 @@ bool InsertText(const base::string16& text, aura::RootWindow* root_window) { |
| // Handle Backspace and Enter specially: using TextInputClient::InsertText is |
| // very unreliable for these characters. |
| - // TODO(bryeung): remove this code once virtual keyboards are able to send |
| + // TODO(kevers): remove this code once virtual keyboards are able to send |
| // these events directly via the Input Injection API. |
| if (text.length() == 1) { |
| ui::KeyboardCode code = ui::VKEY_UNKNOWN; |
| @@ -64,6 +123,37 @@ bool InsertText(const base::string16& text, aura::RootWindow* root_window) { |
| return true; |
| } |
| +bool DispatchKeyEvent(const std::string type, |
| + int char_code, |
| + aura::RootWindow* root_window) { |
| + ui::EventType event_type = ui::ET_UNKNOWN; |
| + if (type == kKeyPressed) |
| + event_type = ui::ET_KEY_PRESSED; |
| + else if (type == kKeyReleased) |
| + event_type = ui::ET_KEY_RELEASED; |
| + if (event_type == ui::ET_UNKNOWN) |
| + return false; |
| + |
| + ui::KeyEvent event = CreateFabricatedKeyEvent(event_type, char_code); |
| + if (event.key_code() != ui::VKEY_UNKNOWN) { |
| + root_window->AsRootWindowHostDelegate()->OnHostKeyEvent(&event); |
| + } else if (event_type == ui::ET_KEY_RELEASED) { |
| + // Though the KeyEvent has setters for unicode characters that are intended |
| + // for use with a virtual keyboard, these values are ignored further down |
| + // the pipeline, relying on the key code. The key code is 0 for most |
| + // characters not found on a US-English keyboard (the assumed configuration |
| + // for fabricated key events). Fall back on inserting raw text as a short- |
| + // term measure. |
| + // TODO(kevers): Fix handling of unicode characters to unify the code |
| + // paths and fix use cases where raw injection fails. |
| + base::string16 text; |
| + base::char16 chars[] = {static_cast<char16>(char_code), 0}; |
| + text.append(chars); |
| + return InsertText(text, root_window); |
| + } |
| + return true; |
| +} |
| + |
| const GritResourceMap* GetKeyboardExtensionResources(size_t* size) { |
| // This looks a lot like the contents of a resource map; however it is |
| // necessary to have a custom path for the extension path, so the resource |