1 // Copyright 2014 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 #ifndef CHROME_BROWSER_CHROMEOS_EVENTS_EVENT_REWRITER_H_ 6 #define CHROME_BROWSER_CHROMEOS_EVENTS_EVENT_REWRITER_H_ 7 8 #include <map> 9 #include <set> 10 #include <string> 11 12 #include "base/compiler_specific.h" 13 #include "base/containers/hash_tables.h" 14 #include "base/memory/scoped_ptr.h" 15 #include "ui/events/event.h" 16 #include "ui/events/event_rewriter.h" 17 18 #if defined(USE_X11) 19 #include "chrome/browser/chromeos/device_hierarchy_observer.h" 20 #include "ui/events/platform/platform_event_observer.h" 21 typedef union _XEvent XEvent; 22 #endif 23 24 class PrefService; 25 26 namespace chromeos { 27 namespace input_method { 28 class ImeKeyboard; 29 } 30 31 // EventRewriter makes various changes to keyboard-related events, 32 // including KeyEvents and some other events with keyboard modifier flags: 33 // - maps modifiers keys (Control, Alt, Search, Caps, Diamond) according 34 // to user preferences; 35 // - maps Command to Control on Apple keyboards; 36 // - converts numeric pad editing keys to their numeric forms; 37 // - converts top-row function keys to special keys where necessary; 38 // - handles various key combinations like Search+Backspace -> Delete 39 // and Search+number to Fnumber; 40 // - handles key/pointer combinations like Alt+Button1 -> Button3. 41 class EventRewriter 42 : 43 #if defined(USE_X11) 44 public DeviceHierarchyObserver, 45 public ui::PlatformEventObserver, 46 #endif 47 public ui::EventRewriter { 48 public: 49 enum DeviceType { 50 kDeviceUnknown = 0, 51 kDeviceAppleKeyboard, 52 }; 53 54 EventRewriter(); 55 virtual ~EventRewriter(); 56 57 // Calls DeviceAddedInternal. 58 DeviceType DeviceAddedForTesting(int device_id, 59 const std::string& device_name); 60 61 // Calls RewriteLocatedEvent(). 62 void RewriteLocatedEventForTesting(const ui::Event& event, int* flags); 63 64 #if defined(USE_X11) device_id_to_type_for_testing()65 const std::map<int, DeviceType>& device_id_to_type_for_testing() const { 66 return device_id_to_type_; 67 } 68 #endif 69 set_last_device_id_for_testing(int device_id)70 void set_last_device_id_for_testing(int device_id) { 71 last_device_id_ = device_id; 72 } set_pref_service_for_testing(const PrefService * pref_service)73 void set_pref_service_for_testing(const PrefService* pref_service) { 74 pref_service_for_testing_ = pref_service; 75 } set_ime_keyboard_for_testing(chromeos::input_method::ImeKeyboard * ime_keyboard)76 void set_ime_keyboard_for_testing( 77 chromeos::input_method::ImeKeyboard* ime_keyboard) { 78 ime_keyboard_for_testing_ = ime_keyboard; 79 } 80 81 // EventRewriter overrides: 82 virtual ui::EventRewriteStatus RewriteEvent( 83 const ui::Event& event, 84 scoped_ptr<ui::Event>* rewritten_event) OVERRIDE; 85 virtual ui::EventRewriteStatus NextDispatchEvent( 86 const ui::Event& last_event, 87 scoped_ptr<ui::Event>* new_event) OVERRIDE; 88 89 #if defined(USE_X11) 90 // ui::PlatformEventObserver: 91 virtual void WillProcessEvent(const ui::PlatformEvent& event) OVERRIDE; 92 virtual void DidProcessEvent(const ui::PlatformEvent& event) OVERRIDE; 93 94 // DeviceHierarchyObserver: 95 virtual void DeviceHierarchyChanged() OVERRIDE; 96 virtual void DeviceAdded(int device_id) OVERRIDE; 97 virtual void DeviceRemoved(int device_id) OVERRIDE; 98 #endif 99 100 private: 101 // Things that internal rewriter phases can change about an Event. 102 struct MutableKeyState { 103 int flags; 104 ui::KeyboardCode key_code; 105 }; 106 107 // Tables of direct remappings for |RewriteWithKeyboardRemappingsByKeyCode()|. 108 struct KeyboardRemapping { 109 ui::KeyboardCode input_key_code; 110 int input_flags; 111 ui::KeyboardCode output_key_code; 112 int output_flags; 113 }; 114 115 #if defined(USE_X11) 116 void DeviceKeyPressedOrReleased(int device_id); 117 #endif 118 119 // Returns the PrefService that should be used. 120 const PrefService* GetPrefService() const; 121 122 // Checks the type of the |device_name|, and inserts a new entry to 123 // |device_id_to_type_|. 124 DeviceType DeviceAddedInternal(int device_id, const std::string& device_name); 125 126 // Returns true if |last_device_id_| is Apple's. 127 bool IsAppleKeyboard() const; 128 129 // Returns true if the target for |event| would prefer to receive raw function 130 // keys instead of having them rewritten into back, forward, brightness, 131 // volume, etc. or if the user has specified that they desire top-row keys to 132 // be treated as function keys globally. 133 bool TopRowKeysAreFunctionKeys(const ui::KeyEvent& event) const; 134 135 // Given modifier flags |original_flags|, returns the remapped modifiers 136 // according to user preferences and/or event properties. 137 int GetRemappedModifierMasks(const PrefService& pref_service, 138 const ui::Event& event, 139 int original_flags) const; 140 141 // Given a set of KeyboardRemapping structs, it finds a matching struct 142 // if possible, and updates the remapped event values. Returns true if a 143 // remapping was found and remapped values were updated. 144 bool RewriteWithKeyboardRemappingsByKeyCode( 145 const KeyboardRemapping* remappings, 146 size_t num_remappings, 147 const MutableKeyState& input, 148 MutableKeyState* remapped_state); 149 150 // Rewrite a particular kind of event. 151 ui::EventRewriteStatus RewriteKeyEvent( 152 const ui::KeyEvent& key_event, 153 scoped_ptr<ui::Event>* rewritten_event); 154 ui::EventRewriteStatus RewriteMouseEvent( 155 const ui::MouseEvent& mouse_event, 156 scoped_ptr<ui::Event>* rewritten_event); 157 ui::EventRewriteStatus RewriteTouchEvent( 158 const ui::TouchEvent& touch_event, 159 scoped_ptr<ui::Event>* rewritten_event); 160 161 // Rewriter phases. These can inspect the original |event|, but operate using 162 // the current |state|, which may have been modified by previous phases. 163 void RewriteModifierKeys(const ui::KeyEvent& event, MutableKeyState* state); 164 void RewriteNumPadKeys(const ui::KeyEvent& event, MutableKeyState* state); 165 void RewriteExtendedKeys(const ui::KeyEvent& event, MutableKeyState* state); 166 void RewriteFunctionKeys(const ui::KeyEvent& event, MutableKeyState* state); 167 void RewriteLocatedEvent(const ui::Event& event, int* flags); 168 169 // A set of device IDs whose press event has been rewritten. 170 std::set<int> pressed_device_ids_; 171 172 std::map<int, DeviceType> device_id_to_type_; 173 int last_device_id_; 174 175 chromeos::input_method::ImeKeyboard* ime_keyboard_for_testing_; 176 const PrefService* pref_service_for_testing_; 177 178 DISALLOW_COPY_AND_ASSIGN(EventRewriter); 179 }; 180 181 } // namespace chromeos 182 183 #endif // CHROME_BROWSER_CHROMEOS_EVENTS_EVENT_REWRITER_H_ 184