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/event_utils.h"
10 #include "ui/events/keycodes/dom4/keycode_converter.h"
11 #include "ui/events/ozone/evdev/event_modifiers_evdev.h"
12 #include "ui/events/ozone/evdev/keyboard_util_evdev.h"
13 #include "ui/events/ozone/layout/keyboard_layout_engine.h"
14 #include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
15 #include "ui/events/ozone/layout/layout_util.h"
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
;
51 KeyboardEvdev::KeyboardEvdev(EventModifiersEvdev
* modifiers
,
52 KeyboardLayoutEngine
* keyboard_layout_engine
,
53 const EventDispatchCallback
& callback
)
54 : callback_(callback
),
55 modifiers_(modifiers
),
56 keyboard_layout_engine_(keyboard_layout_engine
),
57 repeat_enabled_(true),
58 repeat_key_(KEY_RESERVED
) {
59 repeat_delay_
= base::TimeDelta::FromMilliseconds(kRepeatDelayMs
);
60 repeat_interval_
= base::TimeDelta::FromMilliseconds(kRepeatIntervalMs
);
63 KeyboardEvdev::~KeyboardEvdev() {
66 void KeyboardEvdev::OnKeyChange(unsigned int key
,
68 base::TimeDelta timestamp
) {
72 if (down
== key_state_
.test(key
))
75 // State transition: !(down) -> (down)
79 key_state_
.reset(key
);
81 UpdateKeyRepeat(key
, down
);
82 DispatchKey(key
, down
, false /* repeat */, timestamp
);
85 void KeyboardEvdev::Reset() {
86 for (int key
= 0; key
< KEY_CNT
; ++key
)
87 OnKeyChange(key
, false /* down */, ui::EventTimeForNow());
90 void KeyboardEvdev::SetCapsLockEnabled(bool enabled
) {
91 modifiers_
->SetModifierLock(EVDEV_MODIFIER_CAPS_LOCK
, enabled
);
94 bool KeyboardEvdev::IsCapsLockEnabled() {
95 return (modifiers_
->GetModifierFlags() & EF_CAPS_LOCK_DOWN
) != 0;
98 bool KeyboardEvdev::IsAutoRepeatEnabled() {
99 return repeat_enabled_
;
102 void KeyboardEvdev::SetAutoRepeatEnabled(bool enabled
) {
103 repeat_enabled_
= enabled
;
106 void KeyboardEvdev::SetAutoRepeatRate(const base::TimeDelta
& delay
,
107 const base::TimeDelta
& interval
) {
108 repeat_delay_
= delay
;
109 repeat_interval_
= interval
;
112 void KeyboardEvdev::GetAutoRepeatRate(base::TimeDelta
* delay
,
113 base::TimeDelta
* interval
) {
114 *delay
= repeat_delay_
;
115 *interval
= repeat_interval_
;
118 void KeyboardEvdev::UpdateModifier(int modifier_flag
, bool down
) {
119 if (modifier_flag
== EF_NONE
)
122 int modifier
= EventFlagToEvdevModifier(modifier_flag
);
123 if (modifier
== EVDEV_MODIFIER_NONE
)
126 // TODO post-X11: Revise remapping to not use EF_MOD3_DOWN.
127 // Currently EF_MOD3_DOWN means that the CapsLock key is currently down,
128 // and EF_CAPS_LOCK_DOWN means the caps lock state is enabled (and the
129 // key may or may not be down, but usually isn't). There does need to
130 // to be two different flags, since the physical CapsLock key is subject
131 // to remapping, but the caps lock state (which can be triggered in a
132 // variety of ways) is not.
133 if (modifier
== EVDEV_MODIFIER_CAPS_LOCK
)
134 modifiers_
->UpdateModifier(EVDEV_MODIFIER_MOD3
, down
);
136 modifiers_
->UpdateModifier(modifier
, down
);
139 void KeyboardEvdev::UpdateKeyRepeat(unsigned int key
, bool down
) {
140 if (!repeat_enabled_
)
142 else if (key
!= repeat_key_
&& down
)
144 else if (key
== repeat_key_
&& !down
)
148 void KeyboardEvdev::StartKeyRepeat(unsigned int key
) {
150 repeat_delay_timer_
.Start(
151 FROM_HERE
, repeat_delay_
,
152 base::Bind(&KeyboardEvdev::OnRepeatDelayTimeout
, base::Unretained(this)));
153 repeat_interval_timer_
.Stop();
156 void KeyboardEvdev::StopKeyRepeat() {
157 repeat_key_
= KEY_RESERVED
;
158 repeat_delay_timer_
.Stop();
159 repeat_interval_timer_
.Stop();
162 void KeyboardEvdev::OnRepeatDelayTimeout() {
163 DispatchKey(repeat_key_
, true /* down */, true /* repeat */,
166 repeat_interval_timer_
.Start(
167 FROM_HERE
, repeat_interval_
,
168 base::Bind(&KeyboardEvdev::OnRepeatIntervalTimeout
,
169 base::Unretained(this)));
172 void KeyboardEvdev::OnRepeatIntervalTimeout() {
173 DispatchKey(repeat_key_
, true /* down */, true /* repeat */,
177 void KeyboardEvdev::DispatchKey(unsigned int key
,
180 base::TimeDelta timestamp
) {
182 KeycodeConverter::NativeKeycodeToDomCode(EvdevCodeToNativeCode(key
));
183 // DomCode constants are not included here because of conflicts with
184 // evdev preprocessor macros.
185 if (!static_cast<int>(dom_code
))
187 int flags
= modifiers_
->GetModifierFlags();
189 KeyboardCode key_code
;
191 uint32 platform_keycode
= 0;
192 if (!keyboard_layout_engine_
->Lookup(dom_code
, flags
, &dom_key
, &character
,
193 &key_code
, &platform_keycode
)) {
197 UpdateModifier(ModifierDomKeyToEventFlag(dom_key
), down
);
199 KeyEvent
event(down
? ET_KEY_PRESSED
: ET_KEY_RELEASED
, key_code
, dom_code
,
200 modifiers_
->GetModifierFlags(), dom_key
, character
, timestamp
);
201 if (platform_keycode
)
202 event
.set_platform_keycode(platform_keycode
);
203 callback_
.Run(&event
);