1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "ui/keyboard/keyboard_util.h" 6 7 #include <string> 8 9 #include "base/command_line.h" 10 #include "base/logging.h" 11 #include "base/strings/string16.h" 12 #include "grit/keyboard_resources.h" 13 #include "grit/keyboard_resources_map.h" 14 #include "ui/aura/client/aura_constants.h" 15 #include "ui/aura/root_window.h" 16 #include "ui/base/ime/input_method.h" 17 #include "ui/base/ime/text_input_client.h" 18 #include "ui/keyboard/keyboard_switches.h" 19 20 namespace keyboard { 21 22 bool IsKeyboardEnabled() { 23 return CommandLine::ForCurrentProcess()->HasSwitch( 24 switches::kEnableVirtualKeyboard); 25 } 26 27 bool InsertText(const base::string16& text, aura::RootWindow* root_window) { 28 if (!root_window) 29 return false; 30 31 // Handle Backspace and Enter specially: using TextInputClient::InsertText is 32 // very unreliable for these characters. 33 // TODO(bryeung): remove this code once virtual keyboards are able to send 34 // these events directly via the Input Injection API. 35 if (text.length() == 1) { 36 ui::KeyboardCode code = ui::VKEY_UNKNOWN; 37 if (text[0] == L'\n') 38 code = ui::VKEY_RETURN; 39 else if (text[0] == L'\b') 40 code = ui::VKEY_BACK; 41 42 if (code != ui::VKEY_UNKNOWN) { 43 ui::KeyEvent press_event(ui::ET_KEY_PRESSED, code, 0, 0); 44 root_window->AsRootWindowHostDelegate()->OnHostKeyEvent(&press_event); 45 46 ui::KeyEvent release_event(ui::ET_KEY_RELEASED, code, 0, 0); 47 root_window->AsRootWindowHostDelegate()->OnHostKeyEvent(&release_event); 48 49 return true; 50 } 51 } 52 53 ui::InputMethod* input_method = root_window->GetProperty( 54 aura::client::kRootWindowInputMethodKey); 55 if (!input_method) 56 return false; 57 58 ui::TextInputClient* tic = input_method->GetTextInputClient(); 59 if (!tic || tic->GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) 60 return false; 61 62 tic->InsertText(text); 63 64 return true; 65 } 66 67 // TODO(varunjain): It would be cleaner to have something in the 68 // ui::TextInputClient interface, say MoveCaretInDirection(). The code in 69 // here would get the ui::InputMethod from the root_window, and the 70 // ui::TextInputClient from that (see above in InsertText()). 71 bool MoveCursor(int swipe_direction, 72 int modifier_flags, 73 aura::RootWindow* root_window) { 74 if (!root_window) 75 return false; 76 ui::KeyboardCode codex = ui::VKEY_UNKNOWN; 77 ui::KeyboardCode codey = ui::VKEY_UNKNOWN; 78 if (swipe_direction & kCursorMoveRight) 79 codex = ui::VKEY_RIGHT; 80 else if (swipe_direction & kCursorMoveLeft) 81 codex = ui::VKEY_LEFT; 82 83 if (swipe_direction & kCursorMoveUp) 84 codey = ui::VKEY_UP; 85 else if (swipe_direction & kCursorMoveDown) 86 codey = ui::VKEY_DOWN; 87 88 // First deal with the x movement. 89 if (codex != ui::VKEY_UNKNOWN) { 90 ui::KeyEvent press_event(ui::ET_KEY_PRESSED, codex, modifier_flags, 0); 91 root_window->AsRootWindowHostDelegate()->OnHostKeyEvent(&press_event); 92 ui::KeyEvent release_event(ui::ET_KEY_RELEASED, codex, modifier_flags, 0); 93 root_window->AsRootWindowHostDelegate()->OnHostKeyEvent(&release_event); 94 } 95 96 // Then deal with the y movement. 97 if (codey != ui::VKEY_UNKNOWN) { 98 ui::KeyEvent press_event(ui::ET_KEY_PRESSED, codey, modifier_flags, 0); 99 root_window->AsRootWindowHostDelegate()->OnHostKeyEvent(&press_event); 100 ui::KeyEvent release_event(ui::ET_KEY_RELEASED, codey, modifier_flags, 0); 101 root_window->AsRootWindowHostDelegate()->OnHostKeyEvent(&release_event); 102 } 103 return true; 104 } 105 106 const GritResourceMap* GetKeyboardExtensionResources(size_t* size) { 107 // This looks a lot like the contents of a resource map; however it is 108 // necessary to have a custom path for the extension path, so the resource 109 // map cannot be used directly. 110 static const GritResourceMap kKeyboardResources[] = { 111 {"keyboard/api_adapter.js", IDR_KEYBOARD_API_ADAPTER_JS}, 112 {"keyboard/constants.js", IDR_KEYBOARD_CONSTANTS_JS}, 113 {"keyboard/elements/kb-altkey.html", IDR_KEYBOARD_ELEMENTS_ALTKEY}, 114 {"keyboard/elements/kb-altkey-container.html", 115 IDR_KEYBOARD_ELEMENTS_ALTKEY_CONTAINER}, 116 {"keyboard/elements/kb-altkey-data.html", 117 IDR_KEYBOARD_ELEMENTS_ALTKEY_DATA}, 118 {"keyboard/elements/kb-altkey-set.html", IDR_KEYBOARD_ELEMENTS_ALTKEY_SET}, 119 {"keyboard/elements/kb-key.html", IDR_KEYBOARD_ELEMENTS_KEY}, 120 {"keyboard/elements/kb-key-base.html", IDR_KEYBOARD_ELEMENTS_KEY_BASE}, 121 {"keyboard/elements/kb-key-import.html", 122 IDR_KEYBOARD_ELEMENTS_KEY_IMPORT}, 123 {"keyboard/elements/kb-key-sequence.html", 124 IDR_KEYBOARD_ELEMENTS_KEY_SEQUENCE}, 125 {"keyboard/elements/kb-keyboard.html", IDR_KEYBOARD_ELEMENTS_KEYBOARD}, 126 {"keyboard/elements/kb-keyset.html", IDR_KEYBOARD_ELEMENTS_KEYSET}, 127 {"keyboard/elements/kb-row.html", IDR_KEYBOARD_ELEMENTS_ROW}, 128 {"keyboard/images/keyboard.svg", IDR_KEYBOARD_IMAGES_KEYBOARD}, 129 {"keyboard/images/microphone.svg", IDR_KEYBOARD_IMAGES_MICROPHONE}, 130 {"keyboard/images/microphone-green.svg", 131 IDR_KEYBOARD_IMAGES_MICROPHONE_GREEN}, 132 {"keyboard/index.html", IDR_KEYBOARD_INDEX}, 133 {"keyboard/layouts/dvorak.html", IDR_KEYBOARD_LAYOUTS_DVORAK}, 134 {"keyboard/layouts/latin-accents.js", IDR_KEYBOARD_LAYOUTS_LATIN_ACCENTS}, 135 {"keyboard/layouts/qwerty.html", IDR_KEYBOARD_LAYOUTS_QWERTY}, 136 {"keyboard/layouts/symbol-altkeys.js", 137 IDR_KEYBOARD_LAYOUTS_SYMBOL_ALTKEYS}, 138 {"keyboard/layouts/spacebar-row.html", IDR_KEYBOARD_SPACEBAR_ROW}, 139 {"keyboard/main.js", IDR_KEYBOARD_MAIN_JS}, 140 {"keyboard/manifest.json", IDR_KEYBOARD_MANIFEST}, 141 {"keyboard/main.css", IDR_KEYBOARD_MAIN_CSS}, 142 {"keyboard/polymer.min.js", IDR_KEYBOARD_POLYMER}, 143 {"keyboard/voice_input.js", IDR_KEYBOARD_VOICE_INPUT_JS}, 144 }; 145 static const size_t kKeyboardResourcesSize = arraysize(kKeyboardResources); 146 *size = kKeyboardResourcesSize; 147 return kKeyboardResources; 148 } 149 150 } // namespace keyboard 151