#ifndef CHROME_BROWSER_CHROMEOS_EVENTS_EVENT_REWRITER_H_
#define CHROME_BROWSER_CHROMEOS_EVENTS_EVENT_REWRITER_H_
#include <map>
#include <set>
#include <string>
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/containers/hash_tables.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_pump_observer.h"
#include "chrome/browser/chromeos/device_hierarchy_observer.h"
#include "ui/events/keycodes/keyboard_codes.h"
class PrefService;
typedef union _XEvent XEvent;
namespace chromeos {
class KeyboardDrivenEventRewriter;
namespace input_method {
class XKeyboard;
}
class EventRewriter : public DeviceHierarchyObserver,
public base::MessagePumpObserver {
public:
enum DeviceType {
kDeviceUnknown = 0,
kDeviceAppleKeyboard,
};
EventRewriter();
virtual ~EventRewriter();
DeviceType DeviceAddedForTesting(int device_id,
const std::string& device_name);
void RewriteForTesting(XEvent* event);
const std::map<int, DeviceType>& device_id_to_type_for_testing() const {
return device_id_to_type_;
}
void set_last_device_id_for_testing(int device_id) {
last_device_id_ = device_id;
}
void set_pref_service_for_testing(const PrefService* pref_service) {
pref_service_for_testing_ = pref_service;
}
void set_xkeyboard_for_testing(input_method::XKeyboard* xkeyboard) {
xkeyboard_for_testing_ = xkeyboard;
}
static DeviceType GetDeviceType(const std::string& device_name);
private:
friend class EventRewriterAshTest;
friend class EventRewriterTest;
void DeviceKeyPressedOrReleased(int device_id);
virtual base::EventStatus WillProcessEvent(
const base::NativeEvent& event) OVERRIDE;
virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE;
virtual void DeviceHierarchyChanged() OVERRIDE;
virtual void DeviceAdded(int device_id) OVERRIDE;
virtual void DeviceRemoved(int device_id) OVERRIDE;
typedef unsigned long KeySym;
typedef unsigned char KeyCode;
void RefreshKeycodes();
unsigned char NativeKeySymToNativeKeycode(KeySym keysym);
struct KeyboardRemapping {
KeySym input_keysym;
unsigned int input_native_mods;
KeySym output_keysym;
unsigned int output_native_mods;
};
bool TopRowKeysAreFunctionKeys(XEvent* event) const;
bool RewriteWithKeyboardRemappingsByKeySym(
const KeyboardRemapping* remappings,
size_t num_remappings,
KeySym keysym,
unsigned int native_mods,
KeySym* remapped_native_keysym,
unsigned int* remapped_native_mods);
bool RewriteWithKeyboardRemappingsByKeyCode(
const KeyboardRemapping* remappings,
size_t num_remappings,
KeyCode keycode,
unsigned int native_mods,
KeySym* remapped_native_keysym,
unsigned int* remapped_native_mods);
const PrefService* GetPrefService() const;
void Rewrite(XEvent* event);
bool RewriteModifiers(XEvent* event);
bool RewriteFnKey(XEvent* event);
bool RewriteNumPadKeys(XEvent* event);
bool RewriteExtendedKeys(XEvent* event);
bool RewriteFunctionKeys(XEvent* event);
void RewriteLocatedEvent(XEvent* event);
void OverwriteEvent(XEvent* event,
unsigned int new_native_keycode,
unsigned int new_native_state);
DeviceType DeviceAddedInternal(int device_id, const std::string& device_name);
bool IsAppleKeyboard() const;
void GetRemappedModifierMasks(unsigned int original_native_modifiers,
unsigned int* remapped_native_modifiers) const;
std::map<int, DeviceType> device_id_to_type_;
int last_device_id_;
base::hash_map<unsigned long, unsigned long> keysym_to_keycode_map_;
std::set<int> pressed_device_ids_;
input_method::XKeyboard* xkeyboard_for_testing_;
scoped_ptr<KeyboardDrivenEventRewriter>
keyboard_driven_event_rewriter_;
const PrefService* pref_service_for_testing_;
DISALLOW_COPY_AND_ASSIGN(EventRewriter);
};
}
#endif