15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chromeos/events/event_rewriter.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <vector> 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ash/sticky_keys/sticky_keys_controller.h" 104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/wm/window_state.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/wm/window_util.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/logging.h" 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/macros.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/prefs/pref_service.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/string_util.h" 174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/sys_info.h" 18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/ui/login_display_host_impl.h" 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/extensions/extension_commands_global_registry.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 22b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chromeos/chromeos_switches.h" 23a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "chromeos/ime/ime_keyboard.h" 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/ime/input_method_manager.h" 256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/user_manager/user_manager.h" 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/events/event.h" 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/events/event_utils.h" 28010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/events/keycodes/keyboard_code_conversion.h" 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/window_util.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#if defined(USE_X11) 32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include <X11/extensions/XInput2.h> 33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include <X11/Xlib.h> 34010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Get rid of macros from Xlib.h that conflicts with other parts of the code. 35010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#undef RootWindow 36010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#undef Status 37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/base/x/x11_util.h" 39010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/events/keycodes/keyboard_code_conversion_x.h" 40010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#endif 41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace chromeos { 43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Table of key properties of remappable keys and/or remapping targets. 47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// This is searched in two distinct ways: 48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// - |remap_to| is an |input_method::ModifierKey|, which is the form 49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// held in user preferences. |GetRemappedKey()| maps this to the 50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// corresponding |key_code| and characterstic event |flag|. 51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// - |flag| is a |ui::EventFlags|. |GetRemappedModifierMasks()| maps this 52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// to the corresponding user preference |pref_name| for that flag's 53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// key, so that it can then be remapped as above. 54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// In addition |kModifierRemappingCtrl| is a direct reference to the 55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Control key entry in the table, used in handling Chromebook Diamond 56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// and Apple Command keys. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const struct ModifierRemapping { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int remap_to; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flag; 60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::KeyboardCode key_code; 61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const char* pref_name; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} kModifierRemappings[] = { 63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {input_method::kSearchKey, ui::EF_COMMAND_DOWN, ui::VKEY_LWIN, 64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) prefs::kLanguageRemapSearchKeyTo}, 65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {input_method::kControlKey, ui::EF_CONTROL_DOWN, ui::VKEY_CONTROL, 66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) prefs::kLanguageRemapControlKeyTo}, 67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {input_method::kAltKey, ui::EF_ALT_DOWN, ui::VKEY_MENU, 68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) prefs::kLanguageRemapAltKeyTo}, 69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {input_method::kVoidKey, 0, ui::VKEY_UNKNOWN, NULL}, 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) {input_method::kCapsLockKey, ui::EF_MOD3_DOWN, ui::VKEY_CAPITAL, 71010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) prefs::kLanguageRemapCapsLockKeyTo}, 72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {input_method::kEscapeKey, 0, ui::VKEY_ESCAPE, NULL}, 73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {0, 0, ui::VKEY_F15, prefs::kLanguageRemapDiamondKeyTo}, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ModifierRemapping* kModifierRemappingCtrl = &kModifierRemappings[1]; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Gets a remapped key for |pref_name| key. For example, to find out which 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// key Search is currently remapped to, call the function with 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// prefs::kLanguageRemapSearchKeyTo. 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ModifierRemapping* GetRemappedKey(const std::string& pref_name, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PrefService& pref_service) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pref_service.FindPreference(pref_name.c_str())) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; // The |pref_name| hasn't been registered. On login screen? 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int value = pref_service.GetInteger(pref_name.c_str()); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < arraysize(kModifierRemappings); ++i) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value == kModifierRemappings[i].remap_to) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &kModifierRemappings[i]; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool HasDiamondKey() { 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return CommandLine::ForCurrentProcess()->HasSwitch( 95b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) chromeos::switches::kHasChromeOSDiamondKey); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 98effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool IsISOLevel5ShiftUsedByCurrentInputMethod() { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since both German Neo2 XKB layout and Caps Lock depend on Mod3Mask, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it's not possible to make both features work. For now, we don't remap 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mod3Mask when Neo2 is in use. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(yusukes): Remove the restriction. 103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) input_method::InputMethodManager* manager = 104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) input_method::InputMethodManager::Get(); 105effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return manager->IsISOLevel5ShiftUsedByCurrentInputMethod(); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 10834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)bool IsExtensionCommandRegistered(const ui::KeyEvent& key_event) { 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Some keyboard events for ChromeOS get rewritten, such as: 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Search+Shift+Left gets converted to Shift+Home (BeginDocument). 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // This doesn't make sense if the user has assigned that shortcut 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // to an extension. Because: 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // 1) The extension would, upon seeing a request for Ctrl+Shift+Home have 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // to register for Shift+Home, instead. 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // 2) The conversion is unnecessary, because Shift+Home (BeginDocument) isn't 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // going to be executed. 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Therefore, we skip converting the accelerator if an extension has 1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // registered for this shortcut. 1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Profile* profile = ProfileManager::GetActiveUserProfile(); 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!profile || !extensions::ExtensionCommandsGlobalRegistry::Get(profile)) 1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 12334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) int modifiers = key_event.flags() & (ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | 12434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN); 12534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) ui::Accelerator accelerator(key_event.key_code(), modifiers); 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return extensions::ExtensionCommandsGlobalRegistry::Get(profile) 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ->IsRegistered(accelerator); 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)EventRewriter::DeviceType GetDeviceType(const std::string& device_name) { 131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::vector<std::string> tokens; 132010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Tokenize(device_name, " .", &tokens); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 134010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // If the |device_name| contains the two words, "apple" and "keyboard", treat 135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // it as an Apple keyboard. 136010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool found_apple = false; 137010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool found_keyboard = false; 138010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (size_t i = 0; i < tokens.size(); ++i) { 139010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!found_apple && LowerCaseEqualsASCII(tokens[i], "apple")) 140010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) found_apple = true; 141010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!found_keyboard && LowerCaseEqualsASCII(tokens[i], "keyboard")) 142010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) found_keyboard = true; 143010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (found_apple && found_keyboard) 144010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return EventRewriter::kDeviceAppleKeyboard; 145010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 146010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 147010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return EventRewriter::kDeviceUnknown; 148010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 149010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 150010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} // namespace 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 152116680a4aac90f2aa7413d9095a592090648e557Ben MurdochEventRewriter::EventRewriter(ash::StickyKeysController* sticky_keys_controller) 153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : last_keyboard_device_id_(ui::ED_UNKNOWN_DEVICE), 154010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ime_keyboard_for_testing_(NULL), 155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pref_service_for_testing_(NULL), 156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch sticky_keys_controller_(sticky_keys_controller), 157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_diamond_key_modifier_flags_(ui::EF_NONE) { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EventRewriter::~EventRewriter() { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 163116680a4aac90f2aa7413d9095a592090648e557Ben MurdochEventRewriter::DeviceType EventRewriter::KeyboardDeviceAddedForTesting( 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int device_id, 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& device_name) { 166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Tests must avoid XI2 reserved device IDs. 167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK((device_id < 0) || (device_id > 1)); 168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return KeyboardDeviceAddedInternal(device_id, device_name); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 171116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid EventRewriter::RewriteMouseButtonEventForTesting( 172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const ui::MouseEvent& event, 173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<ui::Event>* rewritten_event) { 174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch RewriteMouseButtonEvent(event, rewritten_event); 175010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 177010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ui::EventRewriteStatus EventRewriter::RewriteEvent( 178010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const ui::Event& event, 179010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<ui::Event>* rewritten_event) { 180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if ((event.type() == ui::ET_KEY_PRESSED) || 181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (event.type() == ui::ET_KEY_RELEASED)) { 182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return RewriteKeyEvent(static_cast<const ui::KeyEvent&>(event), 183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch rewritten_event); 184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if ((event.type() == ui::ET_MOUSE_PRESSED) || 186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (event.type() == ui::ET_MOUSE_RELEASED)) { 187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return RewriteMouseButtonEvent(static_cast<const ui::MouseEvent&>(event), 188116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch rewritten_event); 189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (event.type() == ui::ET_MOUSEWHEEL) { 191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return RewriteMouseWheelEvent( 192116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch static_cast<const ui::MouseWheelEvent&>(event), rewritten_event); 193116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if ((event.type() == ui::ET_TOUCH_PRESSED) || 195116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (event.type() == ui::ET_TOUCH_RELEASED)) { 196116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return RewriteTouchEvent(static_cast<const ui::TouchEvent&>(event), 19746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) rewritten_event); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (event.IsScrollEvent()) { 200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return RewriteScrollEvent(static_cast<const ui::ScrollEvent&>(event), 201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch rewritten_event); 202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return ui::EVENT_REWRITE_CONTINUE; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 206010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ui::EventRewriteStatus EventRewriter::NextDispatchEvent( 207010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const ui::Event& last_event, 208010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<ui::Event>* new_event) { 209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (sticky_keys_controller_) { 210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // In the case of sticky keys, we know what the events obtained here are: 211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // modifier key releases that match the ones previously discarded. So, we 212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // know that they don't have to be passed through the post-sticky key 213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // rewriting phases, |RewriteExtendedKeys()| and |RewriteFunctionKeys()|, 214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // because those phases do nothing with modifier key releases. 215116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return sticky_keys_controller_->NextDispatchEvent(new_event); 216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 217010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) NOTREACHED(); 218010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return ui::EVENT_REWRITE_CONTINUE; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 221116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid EventRewriter::BuildRewrittenKeyEvent( 222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const ui::KeyEvent& key_event, 223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ui::KeyboardCode key_code, 224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int flags, 225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<ui::Event>* rewritten_event) { 226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ui::KeyEvent* rewritten_key_event = NULL; 227010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#if defined(USE_X11) 228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch XEvent* xev = key_event.native_event(); 229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (xev) { 230116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch XEvent xkeyevent; 231116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Convert all XI2-based key events into X11 core-based key events, 232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // until consumers no longer depend on receiving X11 core events. 233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (xev->type == GenericEvent) 234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ui::InitXKeyEventFromXIDeviceEvent(*xev, &xkeyevent); 235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch else 236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch xkeyevent.xkey = xev->xkey; 237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 2386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) unsigned int original_x11_keycode = xkeyevent.xkey.keycode; 239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Update native event to match rewritten |ui::Event|. 240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // The X11 keycode represents a physical key position, so it shouldn't 241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // change unless we have actually changed keys, not just modifiers. 242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // This is one guard against problems like crbug.com/390263. 243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (key_event.key_code() != key_code) { 244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch xkeyevent.xkey.keycode = 245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch XKeyCodeForWindowsKeyCode(key_code, flags, gfx::GetXDisplay()); 246116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ui::KeyEvent x11_key_event(&xkeyevent); 248116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch rewritten_key_event = new ui::KeyEvent(x11_key_event); 2496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // For numpad keys, the key char should always NOT be changed because 2516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // XKeyCodeForWindowsKeyCode method cannot handle non-US keyboard layout. 2526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // The correct key char can be got from original X11 keycode but not for the 2536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // rewritten X11 keycode. 2546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // For Shift+NumpadKey cases, use the rewritten X11 keycode (US layout). 2556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Please see crbug.com/335644. 2566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (key_code >= ui::VKEY_NUMPAD0 && key_code <= ui::VKEY_DIVIDE) { 2576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) XEvent numpad_xevent; 2586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) numpad_xevent.xkey = xkeyevent.xkey; 2596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Remove the shift state before getting key char. 2606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Because X11/XKB sometimes returns unexpected key char for 2616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Shift+NumpadKey. e.g. Shift+Numpad_4 returns 'D', etc. 2626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) numpad_xevent.xkey.state &= ~ShiftMask; 2636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) numpad_xevent.xkey.state |= Mod2Mask; // Always set NumLock mask. 2646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!(flags & ui::EF_SHIFT_DOWN)) 2656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) numpad_xevent.xkey.keycode = original_x11_keycode; 2666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) rewritten_key_event->set_character( 2676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ui::GetCharacterFromXEvent(&numpad_xevent)); 2686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 270010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#endif 271116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!rewritten_key_event) 272116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch rewritten_key_event = new ui::KeyEvent(key_event); 273116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch rewritten_key_event->set_flags(flags); 274116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch rewritten_key_event->set_key_code(key_code); 2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(USE_X11) 2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ui::UpdateX11EventForFlags(rewritten_key_event); 277116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch rewritten_key_event->NormalizeFlags(); 2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 279116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch rewritten_event->reset(rewritten_key_event); 280116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 281116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 282116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid EventRewriter::DeviceKeyPressedOrReleased(int device_id) { 283116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!device_id_to_type_.count(device_id)) 284116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch KeyboardDeviceAdded(device_id); 285116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch last_keyboard_device_id_ = device_id; 286116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 2871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const PrefService* EventRewriter::GetPrefService() const { 2891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (pref_service_for_testing_) 2901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return pref_service_for_testing_; 291a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Profile* profile = ProfileManager::GetActiveUserProfile(); 2921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return profile ? profile->GetPrefs() : NULL; 2931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool EventRewriter::IsAppleKeyboard() const { 296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (last_keyboard_device_id_ == ui::ED_UNKNOWN_DEVICE) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check which device generated |event|. 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<int, DeviceType>::const_iterator iter = 301116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch device_id_to_type_.find(last_keyboard_device_id_); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter == device_id_to_type_.end()) { 303116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LOG(ERROR) << "Device ID " << last_keyboard_device_id_ << " is unknown."; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DeviceType type = iter->second; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type == kDeviceAppleKeyboard; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 311010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool EventRewriter::TopRowKeysAreFunctionKeys(const ui::KeyEvent& event) const { 312010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const PrefService* prefs = GetPrefService(); 313010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (prefs && prefs->FindPreference(prefs::kLanguageSendFunctionKeys) && 314010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) prefs->GetBoolean(prefs::kLanguageSendFunctionKeys)) 315010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return true; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 317010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ash::wm::WindowState* state = ash::wm::GetActiveWindowState(); 318010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return state ? state->top_row_keys_are_function_keys() : false; 319010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 321010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)int EventRewriter::GetRemappedModifierMasks(const PrefService& pref_service, 322010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const ui::Event& event, 323010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int original_flags) const { 324010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int unmodified_flags = original_flags; 325116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int rewritten_flags = current_diamond_key_modifier_flags_; 326010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (size_t i = 0; unmodified_flags && (i < arraysize(kModifierRemappings)); 327010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ++i) { 328116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const ModifierRemapping* remapped_key = NULL; 329010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!(unmodified_flags & kModifierRemappings[i].flag)) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 331010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) switch (kModifierRemappings[i].flag) { 332010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) case ui::EF_COMMAND_DOWN: 333010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Rewrite Command key presses on an Apple keyboard to Control. 334010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (IsAppleKeyboard()) { 335010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_EQ(ui::EF_CONTROL_DOWN, kModifierRemappingCtrl->flag); 336010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) remapped_key = kModifierRemappingCtrl; 337010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 338010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) break; 339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case ui::EF_MOD3_DOWN: 340cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // If EF_MOD3_DOWN is used by the current input method, leave it alone; 341cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // it is not remappable. 342010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (IsISOLevel5ShiftUsedByCurrentInputMethod()) 343010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) continue; 344cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Otherwise, Mod3Mask is set on X events when the Caps Lock key 345cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // is down, but, if Caps Lock is remapped, CapsLock is NOT set, 346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // because pressing the key does not invoke caps lock. So, the 347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // kModifierRemappings[] table uses EF_MOD3_DOWN for the Caps 348cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Lock remapping. 349010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) break; 350010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) default: 351010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) break; 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 353010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!remapped_key && kModifierRemappings[i].pref_name) { 354010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) remapped_key = 355010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GetRemappedKey(kModifierRemappings[i].pref_name, pref_service); 356010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 357010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (remapped_key) { 358010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) unmodified_flags &= ~kModifierRemappings[i].flag; 359010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) rewritten_flags |= remapped_key->flag; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 362010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return rewritten_flags | unmodified_flags; 363010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool EventRewriter::RewriteWithKeyboardRemappingsByKeyCode( 366010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const KeyboardRemapping* remappings, 367010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) size_t num_remappings, 368010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const MutableKeyState& input, 369010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) MutableKeyState* remapped_state) { 370010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (size_t i = 0; i < num_remappings; ++i) { 371010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const KeyboardRemapping& map = remappings[i]; 372010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (input.key_code != map.input_key_code) 373010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) continue; 374010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if ((input.flags & map.input_flags) != map.input_flags) 375010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) continue; 376010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) remapped_state->key_code = map.output_key_code; 377010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) remapped_state->flags = (input.flags & ~map.input_flags) | map.output_flags; 378010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return true; 379010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 380010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return false; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)ui::EventRewriteStatus EventRewriter::RewriteKeyEvent( 38446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const ui::KeyEvent& key_event, 38546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<ui::Event>* rewritten_event) { 38634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) if (IsExtensionCommandRegistered(key_event)) 3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return ui::EVENT_REWRITE_CONTINUE; 388116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (key_event.source_device_id() != ui::ED_UNKNOWN_DEVICE) 389116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DeviceKeyPressedOrReleased(key_event.source_device_id()); 39046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) MutableKeyState state = {key_event.flags(), key_event.key_code()}; 3915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Do not rewrite an event sent by ui_controls::SendKeyPress(). See 3925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // crbug.com/136465. 3935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!(key_event.flags() & ui::EF_FINAL)) { 394116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch RewriteModifierKeys(key_event, &state); 395116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch RewriteNumPadKeys(key_event, &state); 39646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 397116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE; 398116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (sticky_keys_controller_) { 399116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch status = sticky_keys_controller_->RewriteKeyEvent( 400116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch key_event, state.key_code, &state.flags); 401116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (status == ui::EVENT_REWRITE_DISCARD) 402116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return ui::EVENT_REWRITE_DISCARD; 40346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 40434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles) if (!(key_event.flags() & ui::EF_FINAL)) { 405116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch RewriteExtendedKeys(key_event, &state); 406116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch RewriteFunctionKeys(key_event, &state); 407116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 408116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if ((key_event.flags() == state.flags) && 409116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (key_event.key_code() == state.key_code) && 410116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(USE_X11) 411116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // TODO(kpschoedel): This test is present because several consumers of 412116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // key events depend on having a native core X11 event, so we rewrite 413116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // all XI2 key events (GenericEvent) into corresponding core X11 key 414116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // events. Remove this when event consumers no longer care about 415116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // native X11 event details (crbug.com/380349). 416116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (!key_event.HasNativeEvent() || 417116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (key_event.native_event()->type != GenericEvent)) && 41846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif 419116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (status == ui::EVENT_REWRITE_CONTINUE)) { 420116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return ui::EVENT_REWRITE_CONTINUE; 421116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 422116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Sticky keys may have returned a result other than |EVENT_REWRITE_CONTINUE|, 423116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // in which case we need to preserve that return status. Alternatively, we 424116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // might be here because key_event changed, in which case we need to 425116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // return |EVENT_REWRITE_REWRITTEN|. 426116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (status == ui::EVENT_REWRITE_CONTINUE) 427116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch status = ui::EVENT_REWRITE_REWRITTEN; 428116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch BuildRewrittenKeyEvent( 429116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch key_event, state.key_code, state.flags, rewritten_event); 430116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return status; 43146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 43246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 433116680a4aac90f2aa7413d9095a592090648e557Ben Murdochui::EventRewriteStatus EventRewriter::RewriteMouseButtonEvent( 43446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const ui::MouseEvent& mouse_event, 43546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<ui::Event>* rewritten_event) { 43646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int flags = mouse_event.flags(); 43746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) RewriteLocatedEvent(mouse_event, &flags); 438116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE; 439116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (sticky_keys_controller_) 440116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch status = sticky_keys_controller_->RewriteMouseEvent(mouse_event, &flags); 441116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int changed_button = ui::EF_NONE; 442116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if ((mouse_event.type() == ui::ET_MOUSE_PRESSED) || 443116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (mouse_event.type() == ui::ET_MOUSE_RELEASED)) { 444116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch changed_button = RewriteModifierClick(mouse_event, &flags); 445116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 446116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if ((mouse_event.flags() == flags) && 447116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (status == ui::EVENT_REWRITE_CONTINUE)) { 44846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return ui::EVENT_REWRITE_CONTINUE; 449116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 450116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (status == ui::EVENT_REWRITE_CONTINUE) 451116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch status = ui::EVENT_REWRITE_REWRITTEN; 45246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ui::MouseEvent* rewritten_mouse_event = new ui::MouseEvent(mouse_event); 45346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) rewritten_event->reset(rewritten_mouse_event); 45446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) rewritten_mouse_event->set_flags(flags); 4555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(USE_X11) 4565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ui::UpdateX11EventForFlags(rewritten_mouse_event); 4575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 4585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (changed_button != ui::EF_NONE) { 459116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch rewritten_mouse_event->set_changed_button_flags(changed_button); 46046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(USE_X11) 4615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ui::UpdateX11EventForChangedButtonFlags(rewritten_mouse_event); 46246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif 4635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 464116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return status; 465116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 466116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 467116680a4aac90f2aa7413d9095a592090648e557Ben Murdochui::EventRewriteStatus EventRewriter::RewriteMouseWheelEvent( 468116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const ui::MouseWheelEvent& wheel_event, 469116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<ui::Event>* rewritten_event) { 470116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!sticky_keys_controller_) 471116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return ui::EVENT_REWRITE_CONTINUE; 472116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int flags = wheel_event.flags(); 473116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ui::EventRewriteStatus status = 474116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch sticky_keys_controller_->RewriteMouseEvent(wheel_event, &flags); 475116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if ((wheel_event.flags() == flags) && 476116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (status == ui::EVENT_REWRITE_CONTINUE)) { 477116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return ui::EVENT_REWRITE_CONTINUE; 478116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 479116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (status == ui::EVENT_REWRITE_CONTINUE) 480116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch status = ui::EVENT_REWRITE_REWRITTEN; 481116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ui::MouseWheelEvent* rewritten_wheel_event = 482116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new ui::MouseWheelEvent(wheel_event); 483116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch rewritten_event->reset(rewritten_wheel_event); 484116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch rewritten_wheel_event->set_flags(flags); 485116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(USE_X11) 4865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ui::UpdateX11EventForFlags(rewritten_wheel_event); 487116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif 488116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return status; 48946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 49046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 49146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)ui::EventRewriteStatus EventRewriter::RewriteTouchEvent( 49246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const ui::TouchEvent& touch_event, 49346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<ui::Event>* rewritten_event) { 49446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int flags = touch_event.flags(); 49546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) RewriteLocatedEvent(touch_event, &flags); 49646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (touch_event.flags() == flags) 49746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return ui::EVENT_REWRITE_CONTINUE; 49846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ui::TouchEvent* rewritten_touch_event = new ui::TouchEvent(touch_event); 49946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) rewritten_event->reset(rewritten_touch_event); 50046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) rewritten_touch_event->set_flags(flags); 50146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(USE_X11) 5025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ui::UpdateX11EventForFlags(rewritten_touch_event); 50346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif 50446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return ui::EVENT_REWRITE_REWRITTEN; 50546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 50646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 507116680a4aac90f2aa7413d9095a592090648e557Ben Murdochui::EventRewriteStatus EventRewriter::RewriteScrollEvent( 508116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const ui::ScrollEvent& scroll_event, 509116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<ui::Event>* rewritten_event) { 510116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int flags = scroll_event.flags(); 511116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE; 512116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (sticky_keys_controller_) 513116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch status = sticky_keys_controller_->RewriteScrollEvent(scroll_event, &flags); 514116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (status == ui::EVENT_REWRITE_CONTINUE) 515116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return status; 516116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ui::ScrollEvent* rewritten_scroll_event = new ui::ScrollEvent(scroll_event); 517116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch rewritten_event->reset(rewritten_scroll_event); 518116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch rewritten_scroll_event->set_flags(flags); 519116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(USE_X11) 5205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ui::UpdateX11EventForFlags(rewritten_scroll_event); 521116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif 522116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return status; 523116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 524116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 525010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void EventRewriter::RewriteModifierKeys(const ui::KeyEvent& key_event, 526010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) MutableKeyState* state) { 527010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(key_event.type() == ui::ET_KEY_PRESSED || 528010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) key_event.type() == ui::ET_KEY_RELEASED); 529010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do nothing if we have just logged in as guest but have not restarted chrome 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // process yet (so we are still on the login screen). In this situations we 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // have no user profile so can not do anything useful. 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that currently, unlike other accounts, when user logs in as guest, we 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // restart chrome process. In future this is to be changed. 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(glotov): remove the following condition when we do not restart chrome 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when user logs in as guest. 537010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // TODO(kpschoedel): check whether this is still necessary. 5386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (user_manager::UserManager::Get()->IsLoggedInAsGuest() && 5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LoginDisplayHostImpl::default_host()) 540010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 5411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 5421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const PrefService* pref_service = GetPrefService(); 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pref_service) 544010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 546010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) MutableKeyState incoming = *state; 547010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state->flags = ui::EF_NONE; 548010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int characteristic_flag = ui::EF_NONE; 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 550010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // First, remap the key code. 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ModifierRemapping* remapped_key = NULL; 552010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) switch (incoming.key_code) { 553010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // On Chrome OS, F15 (XF86XK_Launch6) with NumLock (Mod2Mask) is sent 554010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // when Diamond key is pressed. 555010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) case ui::VKEY_F15: 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // When diamond key is not available, the configuration UI for Diamond 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // key is not shown. Therefore, ignore the kLanguageRemapDiamondKeyTo 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // syncable pref. 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (HasDiamondKey()) 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remapped_key = 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetRemappedKey(prefs::kLanguageRemapDiamondKeyTo, *pref_service); 562116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Default behavior of F15 is Control, even if --has-chromeos-diamond-key 563116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // is absent, according to unit test comments. 564010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!remapped_key) { 565010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_EQ(ui::VKEY_CONTROL, kModifierRemappingCtrl->key_code); 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remapped_key = kModifierRemappingCtrl; 567116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 568116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // F15 is not a modifier key, so we need to track its state directly. 569116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (key_event.type() == ui::ET_KEY_PRESSED) { 570116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int remapped_flag = remapped_key->flag; 571116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (remapped_key->remap_to == input_method::kCapsLockKey) 572116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch remapped_flag |= ui::EF_CAPS_LOCK_DOWN; 573116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_diamond_key_modifier_flags_ = remapped_flag; 574116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 575116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_diamond_key_modifier_flags_ = ui::EF_NONE; 576010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On Chrome OS, XF86XK_Launch7 (F16) with Mod3Mask is sent when Caps Lock 579effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // is pressed (with one exception: when 580effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // IsISOLevel5ShiftUsedByCurrentInputMethod() is true, the key generates 581effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // XK_ISO_Level3_Shift with Mod3Mask, not XF86XK_Launch7). 582010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) case ui::VKEY_F16: 583010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) characteristic_flag = ui::EF_CAPS_LOCK_DOWN; 584b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) remapped_key = 585b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) GetRemappedKey(prefs::kLanguageRemapCapsLockKeyTo, *pref_service); 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 587010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) case ui::VKEY_LWIN: 588010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) case ui::VKEY_RWIN: 589010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) characteristic_flag = ui::EF_COMMAND_DOWN; 590010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Rewrite Command-L/R key presses on an Apple keyboard to Control. 591010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (IsAppleKeyboard()) { 592010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_EQ(ui::VKEY_CONTROL, kModifierRemappingCtrl->key_code); 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remapped_key = kModifierRemappingCtrl; 594010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else { 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remapped_key = 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetRemappedKey(prefs::kLanguageRemapSearchKeyTo, *pref_service); 597010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Default behavior is Super key, hence don't remap the event if the pref 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // is unavailable. 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 601010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) case ui::VKEY_CONTROL: 602010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) characteristic_flag = ui::EF_CONTROL_DOWN; 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remapped_key = 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetRemappedKey(prefs::kLanguageRemapControlKeyTo, *pref_service); 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 606010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) case ui::VKEY_MENU: 607010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // ALT key 608010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) characteristic_flag = ui::EF_ALT_DOWN; 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remapped_key = 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetRemappedKey(prefs::kLanguageRemapAltKeyTo, *pref_service); 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (remapped_key) { 617010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state->key_code = remapped_key->key_code; 618010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) incoming.flags |= characteristic_flag; 619010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) characteristic_flag = remapped_key->flag; 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Next, remap modifier bits. 623010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state->flags |= 624010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GetRemappedModifierMasks(*pref_service, key_event, incoming.flags); 625010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (key_event.type() == ui::ET_KEY_PRESSED) 626010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state->flags |= characteristic_flag; 627010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) else 628010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state->flags &= ~characteristic_flag; 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Toggle Caps Lock if the remapped key is ui::VKEY_CAPITAL, but do nothing if 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the original key is ui::VKEY_CAPITAL (i.e. a Caps Lock key on an external 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // keyboard is pressed) since X can handle that case. 633010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (key_event.type() == ui::ET_KEY_PRESSED && 634010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) incoming.key_code != ui::VKEY_CAPITAL && 635010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state->key_code == ui::VKEY_CAPITAL) { 636010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) chromeos::input_method::ImeKeyboard* ime_keyboard = 637010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ime_keyboard_for_testing_ 638010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ? ime_keyboard_for_testing_ 639010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : chromeos::input_method::InputMethodManager::Get() 640010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ->GetImeKeyboard(); 641010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ime_keyboard->SetCapsLockEnabled(!ime_keyboard->CapsLockIsEnabled()); 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void EventRewriter::RewriteNumPadKeys(const ui::KeyEvent& key_event, 646010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) MutableKeyState* state) { 647010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(key_event.type() == ui::ET_KEY_PRESSED || 648010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) key_event.type() == ui::ET_KEY_RELEASED); 649010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!(state->flags & ui::EF_NUMPAD_KEY)) 650010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 651010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) MutableKeyState incoming = *state; 652010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 653010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) static const KeyboardRemapping kNumPadRemappings[] = { 654010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_INSERT, ui::EF_NUMPAD_KEY, ui::VKEY_NUMPAD0, ui::EF_NUMPAD_KEY}, 655010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_DELETE, ui::EF_NUMPAD_KEY, ui::VKEY_DECIMAL, ui::EF_NUMPAD_KEY}, 656010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_END, ui::EF_NUMPAD_KEY, ui::VKEY_NUMPAD1, ui::EF_NUMPAD_KEY}, 657010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_DOWN, ui::EF_NUMPAD_KEY, ui::VKEY_NUMPAD2, ui::EF_NUMPAD_KEY}, 658010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_NEXT, ui::EF_NUMPAD_KEY, ui::VKEY_NUMPAD3, ui::EF_NUMPAD_KEY}, 659010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_LEFT, ui::EF_NUMPAD_KEY, ui::VKEY_NUMPAD4, ui::EF_NUMPAD_KEY}, 660010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_CLEAR, ui::EF_NUMPAD_KEY, ui::VKEY_NUMPAD5, ui::EF_NUMPAD_KEY}, 661010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_RIGHT, ui::EF_NUMPAD_KEY, ui::VKEY_NUMPAD6, ui::EF_NUMPAD_KEY}, 662010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_HOME, ui::EF_NUMPAD_KEY, ui::VKEY_NUMPAD7, ui::EF_NUMPAD_KEY}, 663010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_UP, ui::EF_NUMPAD_KEY, ui::VKEY_NUMPAD8, ui::EF_NUMPAD_KEY}, 664010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_PRIOR, ui::EF_NUMPAD_KEY, ui::VKEY_NUMPAD9, ui::EF_NUMPAD_KEY}, 665010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) }; 666010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 667010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RewriteWithKeyboardRemappingsByKeyCode( 668010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) kNumPadRemappings, arraysize(kNumPadRemappings), incoming, state); 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 671010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void EventRewriter::RewriteExtendedKeys(const ui::KeyEvent& key_event, 672010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) MutableKeyState* state) { 673010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(key_event.type() == ui::ET_KEY_PRESSED || 674010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) key_event.type() == ui::ET_KEY_RELEASED); 6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 676010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) MutableKeyState incoming = *state; 6775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool rewritten = false; 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 679010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if ((incoming.flags & (ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN)) == 680010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) (ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN)) { 6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Allow Search to avoid rewriting extended keys. 6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const KeyboardRemapping kAvoidRemappings[] = { 683010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) { // Alt+Backspace 684010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::VKEY_BACK, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN, ui::VKEY_BACK, 685010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::EF_ALT_DOWN, 686010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) }, 687010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) { // Control+Alt+Up 688010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::VKEY_UP, 689010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_COMMAND_DOWN, 690010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::VKEY_UP, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, 691010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) }, 692010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) { // Alt+Up 693010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::VKEY_UP, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN, ui::VKEY_UP, 694010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::EF_ALT_DOWN, 695010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) }, 696010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) { // Control+Alt+Down 697010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::VKEY_DOWN, 698010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_COMMAND_DOWN, 699010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::VKEY_DOWN, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, 700010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) }, 701010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) { // Alt+Down 702010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::VKEY_DOWN, ui::EF_ALT_DOWN | ui::EF_COMMAND_DOWN, ui::VKEY_DOWN, 703010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::EF_ALT_DOWN, 704010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) }}; 705010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 706010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) rewritten = RewriteWithKeyboardRemappingsByKeyCode( 707010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) kAvoidRemappings, arraysize(kAvoidRemappings), incoming, state); 7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 710010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!rewritten && (incoming.flags & ui::EF_COMMAND_DOWN)) { 7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const KeyboardRemapping kSearchRemappings[] = { 712010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) { // Search+BackSpace -> Delete 713010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::VKEY_BACK, ui::EF_COMMAND_DOWN, ui::VKEY_DELETE, 0}, 714010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) { // Search+Left -> Home 715010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::VKEY_LEFT, ui::EF_COMMAND_DOWN, ui::VKEY_HOME, 0}, 716010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) { // Search+Up -> Prior (aka PageUp) 717010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::VKEY_UP, ui::EF_COMMAND_DOWN, ui::VKEY_PRIOR, 0}, 718010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) { // Search+Right -> End 719010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN, ui::VKEY_END, 0}, 720010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) { // Search+Down -> Next (aka PageDown) 721010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::VKEY_DOWN, ui::EF_COMMAND_DOWN, ui::VKEY_NEXT, 0}, 722010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) { // Search+Period -> Insert 723010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::VKEY_OEM_PERIOD, ui::EF_COMMAND_DOWN, ui::VKEY_INSERT, 0}}; 7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 725010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) rewritten = RewriteWithKeyboardRemappingsByKeyCode( 726010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) kSearchRemappings, arraysize(kSearchRemappings), incoming, state); 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 729010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!rewritten && (incoming.flags & ui::EF_ALT_DOWN)) { 730010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) static const KeyboardRemapping kNonSearchRemappings[] = { 731010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) { // Alt+BackSpace -> Delete 732010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::VKEY_BACK, ui::EF_ALT_DOWN, ui::VKEY_DELETE, 0}, 733010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) { // Control+Alt+Up -> Home 734010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::VKEY_UP, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, ui::VKEY_HOME, 0}, 735010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) { // Alt+Up -> Prior (aka PageUp) 736010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::VKEY_UP, ui::EF_ALT_DOWN, ui::VKEY_PRIOR, 0}, 737010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) { // Control+Alt+Down -> End 738010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::VKEY_DOWN, ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN, ui::VKEY_END, 0}, 739010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) { // Alt+Down -> Next (aka PageDown) 740010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::VKEY_DOWN, ui::EF_ALT_DOWN, ui::VKEY_NEXT, 0}}; 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 742010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) rewritten = RewriteWithKeyboardRemappingsByKeyCode( 743010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) kNonSearchRemappings, arraysize(kNonSearchRemappings), incoming, state); 744010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 747010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void EventRewriter::RewriteFunctionKeys(const ui::KeyEvent& key_event, 748010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) MutableKeyState* state) { 749010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CHECK(key_event.type() == ui::ET_KEY_PRESSED || 750010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) key_event.type() == ui::ET_KEY_RELEASED); 751010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) MutableKeyState incoming = *state; 7525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool rewritten = false; 7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 754010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if ((incoming.key_code >= ui::VKEY_F1) && 755010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) (incoming.key_code <= ui::VKEY_F24)) { 756010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // By default the top row (F1-F12) keys are system keys for back, forward, 757010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // brightness, volume, etc. However, windows for v2 apps can optionally 758010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // request raw function keys for these keys. 759010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool top_row_keys_are_function_keys = TopRowKeysAreFunctionKeys(key_event); 760010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool search_is_pressed = (incoming.flags & ui::EF_COMMAND_DOWN) != 0; 761010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 762010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Search? Top Row Result 763010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // ------- -------- ------ 764010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // No Fn Unchanged 765010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // No System Fn -> System 766010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Yes Fn Fn -> System 767010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Yes System Search+Fn -> Fn 768010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (top_row_keys_are_function_keys == search_is_pressed) { 769010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Rewrite the F1-F12 keys on a Chromebook keyboard to system keys. 770010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) static const KeyboardRemapping kFkeysToSystemKeys[] = { 771010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_F1, 0, ui::VKEY_BROWSER_BACK, 0}, 772010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_F2, 0, ui::VKEY_BROWSER_FORWARD, 0}, 773010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_F3, 0, ui::VKEY_BROWSER_REFRESH, 0}, 774010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_F4, 0, ui::VKEY_MEDIA_LAUNCH_APP2, 0}, 775010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_F5, 0, ui::VKEY_MEDIA_LAUNCH_APP1, 0}, 776010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_F6, 0, ui::VKEY_BRIGHTNESS_DOWN, 0}, 777010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_F7, 0, ui::VKEY_BRIGHTNESS_UP, 0}, 778010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_F8, 0, ui::VKEY_VOLUME_MUTE, 0}, 779010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_F9, 0, ui::VKEY_VOLUME_DOWN, 0}, 780010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_F10, 0, ui::VKEY_VOLUME_UP, 0}, 781010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) }; 782010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) MutableKeyState incoming_without_command = incoming; 783010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) incoming_without_command.flags &= ~ui::EF_COMMAND_DOWN; 784010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) rewritten = 785010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RewriteWithKeyboardRemappingsByKeyCode(kFkeysToSystemKeys, 786010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) arraysize(kFkeysToSystemKeys), 787010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) incoming_without_command, 788010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state); 789010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else if (search_is_pressed) { 790010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Allow Search to avoid rewriting F1-F12. 791010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state->flags &= ~ui::EF_COMMAND_DOWN; 792010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) rewritten = true; 7934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 796010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!rewritten && (incoming.flags & ui::EF_COMMAND_DOWN)) { 7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Remap Search+<number> to F<number>. 7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We check the keycode here instead of the keysym, as these keys have 7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // different keysyms when modifiers are pressed, such as shift. 8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(danakj): On some i18n keyboards, these choices will be bad and we 8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // should make layout-specific choices here. For eg. on a french keyboard 8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // "-" and "6" are the same key, so F11 will not be accessible. 8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const KeyboardRemapping kNumberKeysToFkeys[] = { 805010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_1, ui::EF_COMMAND_DOWN, ui::VKEY_F1, 0}, 806010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_2, ui::EF_COMMAND_DOWN, ui::VKEY_F2, 0}, 807010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_3, ui::EF_COMMAND_DOWN, ui::VKEY_F3, 0}, 808010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_4, ui::EF_COMMAND_DOWN, ui::VKEY_F4, 0}, 809010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_5, ui::EF_COMMAND_DOWN, ui::VKEY_F5, 0}, 810010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_6, ui::EF_COMMAND_DOWN, ui::VKEY_F6, 0}, 811010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_7, ui::EF_COMMAND_DOWN, ui::VKEY_F7, 0}, 812010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_8, ui::EF_COMMAND_DOWN, ui::VKEY_F8, 0}, 813010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_9, ui::EF_COMMAND_DOWN, ui::VKEY_F9, 0}, 814010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_0, ui::EF_COMMAND_DOWN, ui::VKEY_F10, 0}, 815010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_OEM_MINUS, ui::EF_COMMAND_DOWN, ui::VKEY_F11, 0}, 816010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) {ui::VKEY_OEM_PLUS, ui::EF_COMMAND_DOWN, ui::VKEY_F12, 0}}; 8175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rewritten = RewriteWithKeyboardRemappingsByKeyCode( 818010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) kNumberKeysToFkeys, arraysize(kNumberKeysToFkeys), incoming, state); 8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 822010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void EventRewriter::RewriteLocatedEvent(const ui::Event& event, 82346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int* flags) { 824010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const PrefService* pref_service = GetPrefService(); 825010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!pref_service) 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 82746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) *flags = GetRemappedModifierMasks(*pref_service, event, *flags); 828116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 829010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 830116680a4aac90f2aa7413d9095a592090648e557Ben Murdochint EventRewriter::RewriteModifierClick(const ui::MouseEvent& mouse_event, 831116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int* flags) { 832116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Remap Alt+Button1 to Button3. 833116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const int kAltLeftButton = (ui::EF_ALT_DOWN | ui::EF_LEFT_MOUSE_BUTTON); 834116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (((*flags & kAltLeftButton) == kAltLeftButton) && 835116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ((mouse_event.type() == ui::ET_MOUSE_PRESSED) || 836116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pressed_device_ids_.count(mouse_event.source_device_id()))) { 837116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *flags &= ~kAltLeftButton; 83846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) *flags |= ui::EF_RIGHT_MOUSE_BUTTON; 839116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (mouse_event.type() == ui::ET_MOUSE_PRESSED) 840116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pressed_device_ids_.insert(mouse_event.source_device_id()); 841116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch else 842116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pressed_device_ids_.erase(mouse_event.source_device_id()); 843116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return ui::EF_RIGHT_MOUSE_BUTTON; 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 845116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return ui::EF_NONE; 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 848116680a4aac90f2aa7413d9095a592090648e557Ben MurdochEventRewriter::DeviceType EventRewriter::KeyboardDeviceAddedInternal( 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int device_id, 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& device_name) { 851010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const DeviceType type = GetDeviceType(device_name); 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == kDeviceAppleKeyboard) { 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Apple keyboard '" << device_name << "' connected: " 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "id=" << device_id; 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Always overwrite the existing device_id since the X server may reuse a 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // device id for an unattached device. 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device_id_to_type_[device_id] = type; 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 862116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid EventRewriter::KeyboardDeviceAdded(int device_id) { 863010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#if defined(USE_X11) 864010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_NE(XIAllDevices, device_id); 865010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_NE(XIAllMasterDevices, device_id); 866010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (device_id == XIAllDevices || device_id == XIAllMasterDevices) { 867010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) LOG(ERROR) << "Unexpected device_id passed: " << device_id; 868010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 869010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 870010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 871010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int ndevices_return = 0; 872010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) XIDeviceInfo* device_info = 873010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) XIQueryDevice(gfx::GetXDisplay(), device_id, &ndevices_return); 874010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 875010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Since |device_id| is neither XIAllDevices nor XIAllMasterDevices, 876010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // the number of devices found should be either 0 (not found) or 1. 877010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!device_info) { 878010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) LOG(ERROR) << "XIQueryDevice: Device ID " << device_id << " is unknown."; 879010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 880010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 881010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 882010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_EQ(1, ndevices_return); 883010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (int i = 0; i < ndevices_return; ++i) { 884010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_EQ(device_id, device_info[i].deviceid); // see the comment above. 885010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(device_info[i].name); 886116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch KeyboardDeviceAddedInternal(device_info[i].deviceid, device_info[i].name); 887010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 888010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 889010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) XIFreeDeviceInfo(device_info); 890116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#else 891116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch KeyboardDeviceAddedInternal(device_id, "keyboard"); 892010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#endif 893116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 894010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 8955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace chromeos 896