Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(80)

Side by Side Diff: ui/events/ozone/evdev/keyboard_evdev.cc

Issue 1287103004: Sync ui/events to chromium @ https://codereview.chromium.org/1210203002 (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: rebased Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/events/ozone/evdev/keyboard_evdev.h ('k') | ui/events/ozone/evdev/keyboard_util_evdev.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 #include "ui/events/ozone/evdev/keyboard_evdev.h"
6
7 #include "base/single_thread_task_runner.h"
8 #include "base/thread_task_runner_handle.h"
9 #include "ui/events/event.h"
10 #include "ui/events/event_constants.h"
11 #include "ui/events/event_utils.h"
12 #include "ui/events/keycodes/dom/keycode_converter.h"
13 #include "ui/events/ozone/evdev/event_modifiers_evdev.h"
14 #include "ui/events/ozone/evdev/keyboard_util_evdev.h"
15 #include "ui/events/ozone/layout/keyboard_layout_engine.h"
16 #include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
17 #include "ui/events/ozone/layout/layout_util.h"
18
19 namespace ui {
20
21 // We can't include ui/events/keycodes/dom/dom_code.h here because of
22 // conflicts with preprocessor macros in <linux/input.h>, so we use the
23 // same underlying data with an additional prefix.
24 #define USB_KEYMAP(usb, xkb, win, mac, code, id) DOM_CODE_ ## id = usb
25 #define USB_KEYMAP_DECLARATION enum class DomCode
26 #include "ui/events/keycodes/dom/keycode_converter_data.inc"
27 #undef USB_KEYMAP
28 #undef USB_KEYMAP_DECLARATION
29
30 namespace {
31
32 const int kRepeatDelayMs = 500;
33 const int kRepeatIntervalMs = 50;
34
35 int EventFlagToEvdevModifier(int flag) {
36 switch (flag) {
37 case EF_CAPS_LOCK_DOWN:
38 return EVDEV_MODIFIER_CAPS_LOCK;
39 case EF_SHIFT_DOWN:
40 return EVDEV_MODIFIER_SHIFT;
41 case EF_CONTROL_DOWN:
42 return EVDEV_MODIFIER_CONTROL;
43 case EF_ALT_DOWN:
44 return EVDEV_MODIFIER_ALT;
45 case EF_ALTGR_DOWN:
46 return EVDEV_MODIFIER_ALTGR;
47 case EF_MOD3_DOWN:
48 return EVDEV_MODIFIER_MOD3;
49 case EF_LEFT_MOUSE_BUTTON:
50 return EVDEV_MODIFIER_LEFT_MOUSE_BUTTON;
51 case EF_MIDDLE_MOUSE_BUTTON:
52 return EVDEV_MODIFIER_MIDDLE_MOUSE_BUTTON;
53 case EF_RIGHT_MOUSE_BUTTON:
54 return EVDEV_MODIFIER_RIGHT_MOUSE_BUTTON;
55 case EF_BACK_MOUSE_BUTTON:
56 return EVDEV_MODIFIER_BACK_MOUSE_BUTTON;
57 case EF_FORWARD_MOUSE_BUTTON:
58 return EVDEV_MODIFIER_FORWARD_MOUSE_BUTTON;
59 case EF_COMMAND_DOWN:
60 return EVDEV_MODIFIER_COMMAND;
61 default:
62 return EVDEV_MODIFIER_NONE;
63 }
64 }
65
66 } // namespace
67
68 KeyboardEvdev::KeyboardEvdev(EventModifiersEvdev* modifiers,
69 KeyboardLayoutEngine* keyboard_layout_engine,
70 const EventDispatchCallback& callback)
71 : callback_(callback),
72 modifiers_(modifiers),
73 keyboard_layout_engine_(keyboard_layout_engine),
74 weak_ptr_factory_(this) {
75 repeat_delay_ = base::TimeDelta::FromMilliseconds(kRepeatDelayMs);
76 repeat_interval_ = base::TimeDelta::FromMilliseconds(kRepeatIntervalMs);
77 }
78
79 KeyboardEvdev::~KeyboardEvdev() {
80 }
81
82 void KeyboardEvdev::OnKeyChange(unsigned int key,
83 bool down,
84 bool suppress_auto_repeat,
85 base::TimeDelta timestamp,
86 int device_id) {
87 if (key > KEY_MAX)
88 return;
89
90 bool was_down = key_state_.test(key);
91 bool is_repeat = down && was_down;
92 if (!down && !was_down)
93 return; // Key already released.
94
95 key_state_.set(key, down);
96 UpdateKeyRepeat(key, down, suppress_auto_repeat, device_id);
97 DispatchKey(key, down, is_repeat, timestamp, device_id);
98 }
99
100 void KeyboardEvdev::SetCapsLockEnabled(bool enabled) {
101 modifiers_->SetModifierLock(EVDEV_MODIFIER_CAPS_LOCK, enabled);
102 }
103
104 bool KeyboardEvdev::IsCapsLockEnabled() {
105 return (modifiers_->GetModifierFlags() & EF_CAPS_LOCK_DOWN) != 0;
106 }
107
108 bool KeyboardEvdev::IsAutoRepeatEnabled() {
109 return auto_repeat_enabled_;
110 }
111
112 void KeyboardEvdev::SetAutoRepeatEnabled(bool enabled) {
113 auto_repeat_enabled_ = enabled;
114 }
115
116 void KeyboardEvdev::SetAutoRepeatRate(const base::TimeDelta& delay,
117 const base::TimeDelta& interval) {
118 repeat_delay_ = delay;
119 repeat_interval_ = interval;
120 }
121
122 void KeyboardEvdev::GetAutoRepeatRate(base::TimeDelta* delay,
123 base::TimeDelta* interval) {
124 *delay = repeat_delay_;
125 *interval = repeat_interval_;
126 }
127
128 void KeyboardEvdev::UpdateModifier(int modifier_flag, bool down) {
129 if (modifier_flag == EF_NONE)
130 return;
131
132 int modifier = EventFlagToEvdevModifier(modifier_flag);
133 if (modifier == EVDEV_MODIFIER_NONE)
134 return;
135
136 // TODO post-X11: Revise remapping to not use EF_MOD3_DOWN.
137 // Currently EF_MOD3_DOWN means that the CapsLock key is currently down,
138 // and EF_CAPS_LOCK_DOWN means the caps lock state is enabled (and the
139 // key may or may not be down, but usually isn't). There does need to
140 // to be two different flags, since the physical CapsLock key is subject
141 // to remapping, but the caps lock state (which can be triggered in a
142 // variety of ways) is not.
143 if (modifier == EVDEV_MODIFIER_CAPS_LOCK)
144 modifiers_->UpdateModifier(EVDEV_MODIFIER_MOD3, down);
145 else
146 modifiers_->UpdateModifier(modifier, down);
147 }
148
149 void KeyboardEvdev::UpdateKeyRepeat(unsigned int key,
150 bool down,
151 bool suppress_auto_repeat,
152 int device_id) {
153 if (!auto_repeat_enabled_ || suppress_auto_repeat)
154 StopKeyRepeat();
155 else if (key != repeat_key_ && down)
156 StartKeyRepeat(key, device_id);
157 else if (key == repeat_key_ && !down)
158 StopKeyRepeat();
159 }
160
161 void KeyboardEvdev::StartKeyRepeat(unsigned int key, int device_id) {
162 repeat_key_ = key;
163 repeat_device_id_ = device_id;
164 repeat_sequence_++;
165
166 ScheduleKeyRepeat(repeat_delay_);
167 }
168
169 void KeyboardEvdev::StopKeyRepeat() {
170 repeat_key_ = KEY_RESERVED;
171 repeat_sequence_++;
172 }
173
174 void KeyboardEvdev::ScheduleKeyRepeat(const base::TimeDelta& delay) {
175 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
176 FROM_HERE, base::Bind(&KeyboardEvdev::OnRepeatTimeout,
177 weak_ptr_factory_.GetWeakPtr(), repeat_sequence_),
178 delay);
179 }
180
181 void KeyboardEvdev::OnRepeatTimeout(unsigned int sequence) {
182 if (repeat_sequence_ != sequence)
183 return;
184
185 // Post a task behind any pending key releases in the message loop
186 // FIFO. This ensures there's no spurious repeats during periods of UI
187 // thread jank.
188 base::ThreadTaskRunnerHandle::Get()->PostTask(
189 FROM_HERE, base::Bind(&KeyboardEvdev::OnRepeatCommit,
190 weak_ptr_factory_.GetWeakPtr(), repeat_sequence_));
191 }
192
193 void KeyboardEvdev::OnRepeatCommit(unsigned int sequence) {
194 if (repeat_sequence_ != sequence)
195 return;
196
197 DispatchKey(repeat_key_, true /* down */, true /* repeat */,
198 EventTimeForNow(), repeat_device_id_);
199
200 ScheduleKeyRepeat(repeat_interval_);
201 }
202
203 void KeyboardEvdev::DispatchKey(unsigned int key,
204 bool down,
205 bool repeat,
206 base::TimeDelta timestamp,
207 int device_id) {
208 DomCode dom_code =
209 KeycodeConverter::NativeKeycodeToDomCode(EvdevCodeToNativeCode(key));
210 if (dom_code == DomCode::DOM_CODE_NONE)
211 return;
212 int flags = modifiers_->GetModifierFlags();
213 DomKey dom_key;
214 KeyboardCode key_code;
215 uint16 character;
216 uint32 platform_keycode = 0;
217 if (!keyboard_layout_engine_->Lookup(dom_code, flags, &dom_key, &character,
218 &key_code, &platform_keycode)) {
219 return;
220 }
221 if (!repeat) {
222 int flag = ModifierDomKeyToEventFlag(dom_key);
223 UpdateModifier(flag, down);
224 // X11 XKB, using the configuration as modified for ChromeOS, always sets
225 // EF_MOD3_DOWN for the physical CapsLock key, even if the layout maps
226 // it to something else, so we imitate this to make certain layouts (e.g.
227 // German Neo2) work. crbug.com/495277
228 if (dom_code == DomCode::DOM_CODE_CAPS_LOCK)
229 UpdateModifier(EF_MOD3_DOWN, down);
230 }
231
232 KeyEvent event(down ? ET_KEY_PRESSED : ET_KEY_RELEASED, key_code, dom_code,
233 modifiers_->GetModifierFlags(), dom_key, character, timestamp);
234 event.set_source_device_id(device_id);
235 if (platform_keycode)
236 event.set_platform_keycode(platform_keycode);
237 callback_.Run(&event);
238 }
239 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/ozone/evdev/keyboard_evdev.h ('k') | ui/events/ozone/evdev/keyboard_util_evdev.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698