1 // Copyright (c) 2012 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.
5 #ifndef CHROME_BROWSER_UI_ASH_EVENT_REWRITER_H_
6 #define CHROME_BROWSER_UI_ASH_EVENT_REWRITER_H_
11 #include "ash/event_rewriter_delegate.h"
12 #include "base/basictypes.h"
13 #include "base/compiler_specific.h"
14 #include "base/containers/hash_tables.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "ui/aura/root_window_observer.h"
17 #include "ui/base/keycodes/keyboard_codes.h"
19 #if defined(OS_CHROMEOS)
20 #include "chrome/browser/chromeos/device_hierarchy_observer.h"
29 #if defined(OS_CHROMEOS)
32 class KeyboardDrivenEventRewriter
;
34 namespace input_method
{
40 class EventRewriter
: public ash::EventRewriterDelegate
,
41 public aura::RootWindowObserver
42 #if defined(OS_CHROMEOS)
43 , public chromeos::DeviceHierarchyObserver
53 virtual ~EventRewriter();
55 // Calls DeviceAddedInternal.
56 DeviceType
DeviceAddedForTesting(int device_id
,
57 const std::string
& device_name
);
59 void RewriteForTesting(ui::KeyEvent
* event
);
61 const std::map
<int, DeviceType
>& device_id_to_type_for_testing() const {
62 return device_id_to_type_
;
64 void set_last_device_id_for_testing(int device_id
) {
65 last_device_id_
= device_id
;
67 void set_pref_service_for_testing(const PrefService
* pref_service
) {
68 pref_service_
= pref_service
;
70 #if defined(OS_CHROMEOS)
71 void set_xkeyboard_for_testing(chromeos::input_method::XKeyboard
* xkeyboard
) {
72 xkeyboard_
= xkeyboard
;
76 // Gets DeviceType from the |device_name|.
77 static DeviceType
GetDeviceType(const std::string
& device_name
);
80 // ash::EventRewriterDelegate overrides:
81 virtual ash::EventRewriterDelegate::Action
RewriteOrFilterKeyEvent(
82 ui::KeyEvent
* event
) OVERRIDE
;
83 virtual ash::EventRewriterDelegate::Action
RewriteOrFilterLocatedEvent(
84 ui::LocatedEvent
* event
) OVERRIDE
;
86 // aura::RootWindowObserver overrides:
87 virtual void OnKeyboardMappingChanged(const aura::RootWindow
* root
) OVERRIDE
;
89 #if defined(OS_CHROMEOS)
90 // chromeos::DeviceHierarchyObserver overrides:
91 virtual void DeviceHierarchyChanged() OVERRIDE
{}
92 virtual void DeviceAdded(int device_id
) OVERRIDE
;
93 virtual void DeviceRemoved(int device_id
) OVERRIDE
;
94 virtual void DeviceKeyPressedOrReleased(int device_id
) OVERRIDE
;
96 // We don't want to include Xlib.h here since it has polluting macros, so
97 // define these locally.
98 typedef unsigned long KeySym
;
99 typedef unsigned char KeyCode
;
101 // Updates |*_xkeycode_| in response to a keyboard map change.
102 void RefreshKeycodes();
103 // Converts an X key symbol like XK_Control_L to a key code.
104 unsigned char NativeKeySymToNativeKeycode(KeySym keysym
);
106 struct KeyboardRemapping
{
108 unsigned int input_mods
;
109 unsigned int input_native_mods
;
110 KeySym output_keysym
;
111 ui::KeyboardCode output_keycode
;
112 unsigned int output_mods
;
113 unsigned int output_native_mods
;
116 // Given a set of KeyboardRemapping structs, it finds a matching struct
117 // if possible, and updates the remapped event values. Returns true if a
118 // remapping was found and remapped values were updated.
119 bool RewriteWithKeyboardRemappingsByKeySym(
120 const KeyboardRemapping
* remappings
,
121 size_t num_remappings
,
123 unsigned int native_mods
,
125 KeySym
* remapped_native_keysym
,
126 unsigned int* remapped_native_mods
,
127 ui::KeyboardCode
* remapped_keycode
,
128 unsigned int* remapped_mods
);
130 // Given a set of KeyboardRemapping structs, it finds a matching struct
131 // if possible, and updates the remapped event values. This function converts
132 // the KeySym in the KeyboardRemapping struct into the KeyCode before matching
133 // to allow any KeyCode on the same physical key as the given KeySym to match.
134 // Returns true if a remapping was found and remapped values were updated.
135 bool RewriteWithKeyboardRemappingsByKeyCode(
136 const KeyboardRemapping
* remappings
,
137 size_t num_remappings
,
139 unsigned int native_mods
,
141 KeySym
* remapped_native_keysym
,
142 unsigned int* remapped_native_mods
,
143 ui::KeyboardCode
* remapped_keycode
,
144 unsigned int* remapped_mods
);
147 // Rewrites the |event| by applying all RewriteXXX functions as needed.
148 void Rewrite(ui::KeyEvent
* event
);
150 // Rewrites a modifier key press/release following the current user
152 bool RewriteModifiers(ui::KeyEvent
* event
);
154 // Rewrites Fn key press/release to Control. In some cases, Fn key is not
155 // intercepted by the EC, but generates a key event like "XK_F15 + Mod3Mask"
156 // as shown in crosbug.com/p/14339.
157 bool RewriteFnKey(ui::KeyEvent
* event
);
159 // Rewrites a NumPad key press/release without Num Lock to a corresponding key
160 // press/release with the lock. Returns true when |event| is rewritten.
161 bool RewriteNumPadKeys(ui::KeyEvent
* event
);
163 // Rewrites Backspace and Arrow keys following the Chrome OS keyboard spec.
164 // * Alt+Backspace -> Delete
165 // * Alt+Up -> Prior (aka PageUp)
166 // * Alt+Down -> Next (aka PageDown)
167 // * Ctrl+Alt+Up -> Home
168 // * Ctrl+Alt+Down -> End
169 // When the Search key acts as a function key, it instead maps:
170 // * Search+Backspace -> Delete
171 // * Search+Up -> Prior (aka PageUp)
172 // * Search+Down -> Next (aka PageDown)
173 // * Search+Left -> Home
174 // * Search+Right -> End
175 // * Search+. -> Insert
176 // Returns true when the |event| is rewritten.
177 bool RewriteExtendedKeys(ui::KeyEvent
* event
);
179 // When the Search key acts as a function key, it remaps Search+1
180 // through Search+= to F1 through F12. Returns true when the |event| is
182 bool RewriteFunctionKeys(ui::KeyEvent
* event
);
184 // Rewrites the located |event|.
185 void RewriteLocatedEvent(ui::LocatedEvent
* event
);
187 // Overwrites |event| with the keycodes and flags.
188 void OverwriteEvent(ui::KeyEvent
* event
,
189 unsigned int new_native_keycode
,
190 unsigned int new_native_state
,
191 ui::KeyboardCode new_keycode
,
194 // Checks the type of the |device_name|, and inserts a new entry to
195 // |device_id_to_type_|.
196 DeviceType
DeviceAddedInternal(int device_id
, const std::string
& device_name
);
198 // Returns true if |last_device_id_| is Apple's.
199 bool IsAppleKeyboard() const;
201 // Remaps |original_flags| to |remapped_flags| and |original_native_modifiers|
202 // to |remapped_native_modifiers| following the current user prefs.
203 void GetRemappedModifierMasks(int original_flags
,
204 unsigned int original_native_modifiers
,
206 unsigned int* remapped_native_modifiers
) const;
208 std::map
<int, DeviceType
> device_id_to_type_
;
211 #if defined(OS_CHROMEOS)
212 // A mapping from X11 KeySym keys to KeyCode values.
213 base::hash_map
<unsigned long, unsigned long> keysym_to_keycode_map_
;
215 chromeos::input_method::XKeyboard
* xkeyboard_
; // for testing.
217 scoped_ptr
<chromeos::KeyboardDrivenEventRewriter
>
218 keyboard_driven_event_rewritter_
;
221 const PrefService
* pref_service_
; // for testing.
223 DISALLOW_COPY_AND_ASSIGN(EventRewriter
);
226 #endif // CHROME_BROWSER_UI_ASH_EVENT_REWRITER_H_