Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / events / event_rewriter.h
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/basictypes.h"
13 #include "base/compiler_specific.h"
14 #include "base/containers/hash_tables.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/message_loop/message_pump_observer.h"
17 #include "chrome/browser/chromeos/device_hierarchy_observer.h"
18 #include "ui/aura/root_window_observer.h"
19 #include "ui/events/keycodes/keyboard_codes.h"
20
21 class PrefService;
22 typedef union _XEvent XEvent;
23
24 namespace aura {
25 class RootWindow;
26 }
27
28 namespace chromeos {
29 class KeyboardDrivenEventRewriter;
30 namespace input_method {
31 class XKeyboard;
32 }
33
34 class EventRewriter : public aura::RootWindowObserver,
35                       public DeviceHierarchyObserver,
36                       public base::MessagePumpObserver {
37  public:
38   enum DeviceType {
39     kDeviceUnknown = 0,
40     kDeviceAppleKeyboard,
41   };
42
43   EventRewriter();
44   virtual ~EventRewriter();
45
46   // Calls DeviceAddedInternal.
47   DeviceType DeviceAddedForTesting(int device_id,
48                                    const std::string& device_name);
49   // Calls Rewrite.
50   void RewriteForTesting(XEvent* event);
51
52   const std::map<int, DeviceType>& device_id_to_type_for_testing() const {
53     return device_id_to_type_;
54   }
55   void set_last_device_id_for_testing(int device_id) {
56     last_device_id_ = device_id;
57   }
58   void set_pref_service_for_testing(const PrefService* pref_service) {
59     pref_service_for_testing_ = pref_service;
60   }
61   void set_xkeyboard_for_testing(input_method::XKeyboard* xkeyboard) {
62     xkeyboard_for_testing_ = xkeyboard;
63   }
64
65   // Gets DeviceType from the |device_name|.
66   static DeviceType GetDeviceType(const std::string& device_name);
67
68  private:
69   friend class EventRewriterAshTest;
70   friend class EventRewriterTest;
71
72   // aura::RootWindowObserver overrides:
73   virtual void OnKeyboardMappingChanged(const aura::RootWindow* root) OVERRIDE;
74
75   // base::MessagePumpObserver overrides:
76   virtual base::EventStatus WillProcessEvent(
77       const base::NativeEvent& event) OVERRIDE;
78   virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE;
79
80   // DeviceHierarchyObserver overrides:
81   virtual void DeviceHierarchyChanged() OVERRIDE {}
82   virtual void DeviceAdded(int device_id) OVERRIDE;
83   virtual void DeviceRemoved(int device_id) OVERRIDE;
84   virtual void DeviceKeyPressedOrReleased(int device_id) OVERRIDE;
85
86   // We don't want to include Xlib.h here since it has polluting macros, so
87   // define these locally.
88   typedef unsigned long KeySym;
89   typedef unsigned char KeyCode;
90
91   // Updates |*_xkeycode_| in response to a keyboard map change.
92   void RefreshKeycodes();
93   // Converts an X key symbol like XK_Control_L to a key code.
94   unsigned char NativeKeySymToNativeKeycode(KeySym keysym);
95
96   struct KeyboardRemapping {
97     KeySym input_keysym;
98     unsigned int input_native_mods;
99     KeySym output_keysym;
100     unsigned int output_native_mods;
101   };
102
103   // Returns true if the target for |event| would prefer to receive raw function
104   // keys instead of having them rewritten into back, forward, brightness,
105   // volume, etc. or if the user has specified that they desire top-row keys to
106   // be treated as function keys globally.
107   bool TopRowKeysAreFunctionKeys(XEvent* event) const;
108
109   // Given a set of KeyboardRemapping structs, it finds a matching struct
110   // if possible, and updates the remapped event values. Returns true if a
111   // remapping was found and remapped values were updated.
112   bool RewriteWithKeyboardRemappingsByKeySym(
113       const KeyboardRemapping* remappings,
114       size_t num_remappings,
115       KeySym keysym,
116       unsigned int native_mods,
117       KeySym* remapped_native_keysym,
118       unsigned int* remapped_native_mods);
119
120   // Given a set of KeyboardRemapping structs, it finds a matching struct
121   // if possible, and updates the remapped event values. This function converts
122   // the KeySym in the KeyboardRemapping struct into the KeyCode before matching
123   // to allow any KeyCode on the same physical key as the given KeySym to match.
124   // Returns true if a remapping was found and remapped values were updated.
125   bool RewriteWithKeyboardRemappingsByKeyCode(
126       const KeyboardRemapping* remappings,
127       size_t num_remappings,
128       KeyCode keycode,
129       unsigned int native_mods,
130       KeySym* remapped_native_keysym,
131       unsigned int* remapped_native_mods);
132
133   // Returns the PrefService that should be used.
134   const PrefService* GetPrefService() const;
135
136   // Rewrites the |event| by applying all RewriteXXX functions as needed.
137   void Rewrite(XEvent* event);
138
139   // Rewrites a modifier key press/release following the current user
140   // preferences.
141   bool RewriteModifiers(XEvent* event);
142
143   // Rewrites Fn key press/release to Control. In some cases, Fn key is not
144   // intercepted by the EC, but generates a key event like "XK_F15 + Mod3Mask"
145   // as shown in crosbug.com/p/14339.
146   bool RewriteFnKey(XEvent* event);
147
148   // Rewrites a NumPad key press/release without Num Lock to a corresponding key
149   // press/release with the lock.  Returns true when |event| is rewritten.
150   bool RewriteNumPadKeys(XEvent* event);
151
152   // Rewrites Backspace and Arrow keys following the Chrome OS keyboard spec.
153   //  * Alt+Backspace -> Delete
154   //  * Alt+Up -> Prior (aka PageUp)
155   //  * Alt+Down -> Next (aka PageDown)
156   //  * Ctrl+Alt+Up -> Home
157   //  * Ctrl+Alt+Down -> End
158   // When the Search key acts as a function key, it instead maps:
159   //  * Search+Backspace -> Delete
160   //  * Search+Up -> Prior (aka PageUp)
161   //  * Search+Down -> Next (aka PageDown)
162   //  * Search+Left -> Home
163   //  * Search+Right -> End
164   //  * Search+. -> Insert
165   // Returns true when the |event| is rewritten.
166   bool RewriteExtendedKeys(XEvent* event);
167
168   // When the Search key acts as a function key, it remaps Search+1
169   // through Search+= to F1 through F12. Returns true when the |event| is
170   // rewritten.
171   bool RewriteFunctionKeys(XEvent* event);
172
173   // Rewrites the located |event|.
174   void RewriteLocatedEvent(XEvent* event);
175
176   // Overwrites |event| with the keycodes and flags.
177   void OverwriteEvent(XEvent* event,
178                       unsigned int new_native_keycode,
179                       unsigned int new_native_state);
180
181   // Checks the type of the |device_name|, and inserts a new entry to
182   // |device_id_to_type_|.
183   DeviceType DeviceAddedInternal(int device_id, const std::string& device_name);
184
185   // Returns true if |last_device_id_| is Apple's.
186   bool IsAppleKeyboard() const;
187
188   // Remaps |original_native_modifiers| to |remapped_native_modifiers| following
189   // the current user prefs.
190   void GetRemappedModifierMasks(unsigned int original_native_modifiers,
191                                 unsigned int* remapped_native_modifiers) const;
192
193   std::map<int, DeviceType> device_id_to_type_;
194   int last_device_id_;
195
196   // A mapping from X11 KeySym keys to KeyCode values.
197   base::hash_map<unsigned long, unsigned long> keysym_to_keycode_map_;
198
199   // A set of device IDs whose press event has been rewritten.
200   std::set<int> pressed_device_ids_;
201
202   input_method::XKeyboard* xkeyboard_for_testing_;
203
204   scoped_ptr<KeyboardDrivenEventRewriter>
205       keyboard_driven_event_rewriter_;
206
207   const PrefService* pref_service_for_testing_;
208
209   DISALLOW_COPY_AND_ASSIGN(EventRewriter);
210 };
211
212 }  // namespace chromeos
213
214 #endif  // CHROME_BROWSER_CHROMEOS_EVENTS_EVENT_REWRITER_H_