Home | History | Annotate | Download | only in events
      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)
     65   const std::map<int, DeviceType>& device_id_to_type_for_testing() const {
     66     return device_id_to_type_;
     67   }
     68 #endif
     69 
     70   void set_last_device_id_for_testing(int device_id) {
     71     last_device_id_ = device_id;
     72   }
     73   void set_pref_service_for_testing(const PrefService* pref_service) {
     74     pref_service_for_testing_ = pref_service;
     75   }
     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