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.
5 #include "ui/events/ozone/evdev/keyboard_evdev.h"
7 #include "ui/events/event.h"
8 #include "ui/events/event_constants.h"
9 #include "ui/events/keycodes/dom4/keycode_converter.h"
10 #include "ui/events/ozone/evdev/event_modifiers_evdev.h"
11 #include "ui/events/ozone/layout/keyboard_layout_engine.h"
12 #include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
13 #include "ui/events/ozone/layout/layout_util.h"
19 const int kXkbKeycodeOffset
= 8;
21 const int kRepeatDelayMs
= 500;
22 const int kRepeatIntervalMs
= 50;
24 int EventFlagToEvdevModifier(int flag
) {
26 case EF_CAPS_LOCK_DOWN
:
27 return EVDEV_MODIFIER_CAPS_LOCK
;
29 return EVDEV_MODIFIER_SHIFT
;
31 return EVDEV_MODIFIER_CONTROL
;
33 return EVDEV_MODIFIER_ALT
;
35 return EVDEV_MODIFIER_ALTGR
;
36 case EF_LEFT_MOUSE_BUTTON
:
37 return EVDEV_MODIFIER_LEFT_MOUSE_BUTTON
;
38 case EF_MIDDLE_MOUSE_BUTTON
:
39 return EVDEV_MODIFIER_MIDDLE_MOUSE_BUTTON
;
40 case EF_RIGHT_MOUSE_BUTTON
:
41 return EVDEV_MODIFIER_RIGHT_MOUSE_BUTTON
;
43 return EVDEV_MODIFIER_COMMAND
;
45 return EVDEV_MODIFIER_NONE
;
49 bool IsModifierLock(int evdev_modifier
) {
50 return evdev_modifier
== EVDEV_MODIFIER_CAPS_LOCK
;
55 KeyboardEvdev::KeyboardEvdev(EventModifiersEvdev
* modifiers
,
56 KeyboardLayoutEngine
* keyboard_layout_engine
,
57 const EventDispatchCallback
& callback
)
58 : callback_(callback
),
59 modifiers_(modifiers
),
60 keyboard_layout_engine_(keyboard_layout_engine
),
61 repeat_enabled_(true),
62 repeat_key_(KEY_RESERVED
) {
63 repeat_delay_
= base::TimeDelta::FromMilliseconds(kRepeatDelayMs
);
64 repeat_interval_
= base::TimeDelta::FromMilliseconds(kRepeatIntervalMs
);
67 KeyboardEvdev::~KeyboardEvdev() {
70 void KeyboardEvdev::OnKeyChange(unsigned int key
, bool down
) {
74 if (down
== key_state_
.test(key
))
77 // State transition: !(down) -> (down)
81 key_state_
.reset(key
);
83 UpdateKeyRepeat(key
, down
);
84 DispatchKey(key
, down
, false /* repeat */);
87 bool KeyboardEvdev::IsAutoRepeatEnabled() {
88 return repeat_enabled_
;
91 void KeyboardEvdev::SetAutoRepeatEnabled(bool enabled
) {
92 repeat_enabled_
= enabled
;
95 void KeyboardEvdev::SetAutoRepeatRate(const base::TimeDelta
& delay
,
96 const base::TimeDelta
& interval
) {
97 repeat_delay_
= delay
;
98 repeat_interval_
= interval
;
101 void KeyboardEvdev::GetAutoRepeatRate(base::TimeDelta
* delay
,
102 base::TimeDelta
* interval
) {
103 *delay
= repeat_delay_
;
104 *interval
= repeat_interval_
;
107 void KeyboardEvdev::UpdateModifier(int modifier_flag
, bool down
) {
108 if (modifier_flag
== EF_NONE
)
111 int modifier
= EventFlagToEvdevModifier(modifier_flag
);
112 if (modifier
== EVDEV_MODIFIER_NONE
)
115 if (IsModifierLock(modifier
))
116 modifiers_
->UpdateModifierLock(modifier
, down
);
118 modifiers_
->UpdateModifier(modifier
, down
);
121 void KeyboardEvdev::UpdateKeyRepeat(unsigned int key
, bool down
) {
122 if (!repeat_enabled_
)
124 else if (key
!= repeat_key_
&& down
)
126 else if (key
== repeat_key_
&& !down
)
130 void KeyboardEvdev::StartKeyRepeat(unsigned int key
) {
132 repeat_delay_timer_
.Start(
133 FROM_HERE
, repeat_delay_
,
134 base::Bind(&KeyboardEvdev::OnRepeatDelayTimeout
, base::Unretained(this)));
135 repeat_interval_timer_
.Stop();
138 void KeyboardEvdev::StopKeyRepeat() {
139 repeat_key_
= KEY_RESERVED
;
140 repeat_delay_timer_
.Stop();
141 repeat_interval_timer_
.Stop();
144 void KeyboardEvdev::OnRepeatDelayTimeout() {
145 DispatchKey(repeat_key_
, true /* down */, true /* repeat */);
147 repeat_interval_timer_
.Start(
148 FROM_HERE
, repeat_interval_
,
149 base::Bind(&KeyboardEvdev::OnRepeatIntervalTimeout
,
150 base::Unretained(this)));
153 void KeyboardEvdev::OnRepeatIntervalTimeout() {
154 DispatchKey(repeat_key_
, true /* down */, true /* repeat */);
157 void KeyboardEvdev::DispatchKey(unsigned int key
, bool down
, bool repeat
) {
159 KeycodeConverter::NativeKeycodeToDomCode(key
+ kXkbKeycodeOffset
);
160 // DomCode constants are not included here because of conflicts with
161 // evdev preprocessor macros.
162 if (!static_cast<int>(dom_code
))
164 int flags
= modifiers_
->GetModifierFlags();
166 KeyboardCode key_code
;
168 uint32 platform_keycode
= 0;
169 if (!keyboard_layout_engine_
->Lookup(dom_code
, flags
, &dom_key
, &character
,
170 &key_code
, &platform_keycode
)) {
174 UpdateModifier(ModifierDomKeyToEventFlag(dom_key
), down
);
177 new KeyEvent(down
? ET_KEY_PRESSED
: ET_KEY_RELEASED
, key_code
, dom_code
,
178 modifiers_
->GetModifierFlags(), dom_key
, character
);
179 if (platform_keycode
)
180 event
->set_platform_keycode(platform_keycode
);
181 callback_
.Run(make_scoped_ptr(event
));
185 int KeyboardEvdev::NativeCodeToEvdevCode(int native_code
) {
186 if (native_code
== KeycodeConverter::InvalidNativeKeycode()) {
189 return native_code
- kXkbKeycodeOffset
;