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

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

Issue 985163002: ozone: evdev: Fix possibility of stuck keys (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/events/ozone/evdev/event_converter_evdev_impl.h" 5 #include "ui/events/ozone/evdev/event_converter_evdev_impl.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <linux/input.h> 8 #include <linux/input.h>
9 9
10 #include "ui/events/event.h" 10 #include "ui/events/event.h"
11 #include "ui/events/event_utils.h"
11 #include "ui/events/keycodes/dom4/keycode_converter.h" 12 #include "ui/events/keycodes/dom4/keycode_converter.h"
12 #include "ui/events/ozone/evdev/device_event_dispatcher_evdev.h" 13 #include "ui/events/ozone/evdev/device_event_dispatcher_evdev.h"
13 #include "ui/events/ozone/evdev/keyboard_util_evdev.h" 14 #include "ui/events/ozone/evdev/keyboard_util_evdev.h"
14 15
15 namespace ui { 16 namespace ui {
16 17
17 namespace { 18 namespace {
18 19
19 // Values for EV_KEY. 20 // Values for EV_KEY.
20 const int kKeyReleaseValue = 0; 21 const int kKeyReleaseValue = 0;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 scoped_ptr<std::set<DomCode>> allowed_keys) { 83 scoped_ptr<std::set<DomCode>> allowed_keys) {
83 DCHECK(HasKeyboard()); 84 DCHECK(HasKeyboard());
84 allowed_keys_ = allowed_keys.Pass(); 85 allowed_keys_ = allowed_keys.Pass();
85 } 86 }
86 87
87 void EventConverterEvdevImpl::AllowAllKeys() { 88 void EventConverterEvdevImpl::AllowAllKeys() {
88 DCHECK(HasKeyboard()); 89 DCHECK(HasKeyboard());
89 allowed_keys_.reset(); 90 allowed_keys_.reset();
90 } 91 }
91 92
93 void EventConverterEvdevImpl::OnStopped() {
94 ReleaseKeys();
95 }
96
92 void EventConverterEvdevImpl::ProcessEvents(const input_event* inputs, 97 void EventConverterEvdevImpl::ProcessEvents(const input_event* inputs,
93 int count) { 98 int count) {
94 for (int i = 0; i < count; ++i) { 99 for (int i = 0; i < count; ++i) {
95 const input_event& input = inputs[i]; 100 const input_event& input = inputs[i];
96 switch (input.type) { 101 switch (input.type) {
97 case EV_KEY: 102 case EV_KEY:
98 ConvertKeyEvent(input); 103 ConvertKeyEvent(input);
99 break; 104 break;
100 case EV_REL: 105 case EV_REL:
101 ConvertMouseMoveEvent(input); 106 ConvertMouseMoveEvent(input);
102 break; 107 break;
103 case EV_SYN: 108 case EV_SYN:
104 if (input.code == SYN_DROPPED) 109 if (input.code == SYN_DROPPED)
105 LOG(WARNING) << "kernel dropped input events"; 110 OnLostSync();
106 FlushEvents(input); 111 else if (input.code == SYN_REPORT)
112 FlushEvents(input);
107 break; 113 break;
108 } 114 }
109 } 115 }
110 } 116 }
111 117
112 void EventConverterEvdevImpl::ConvertKeyEvent(const input_event& input) { 118 void EventConverterEvdevImpl::ConvertKeyEvent(const input_event& input) {
113 // Ignore repeat events. 119 // Ignore repeat events.
114 if (input.value == kKeyRepeatValue) 120 if (input.value == kKeyRepeatValue)
115 return; 121 return;
116 122
117 // Mouse processing. 123 // Mouse processing.
118 if (input.code >= BTN_MOUSE && input.code < BTN_JOYSTICK) { 124 if (input.code >= BTN_MOUSE && input.code < BTN_JOYSTICK) {
119 DispatchMouseButton(input); 125 DispatchMouseButton(input);
120 return; 126 return;
121 } 127 }
122 128
123 // Keyboard processing. 129 // Keyboard processing.
124 DomCode key_code = KeycodeConverter::NativeKeycodeToDomCode( 130 OnKeyChange(input.code, input.value != kKeyReleaseValue,
125 EvdevCodeToNativeCode(input.code)); 131 TimeDeltaFromInputEvent(input));
126 if (!allowed_keys_ || allowed_keys_->count(key_code)) {
127 dispatcher_->DispatchKeyEvent(
128 KeyEventParams(id_, input.code, input.value != kKeyReleaseValue,
129 TimeDeltaFromInputEvent(input)));
130 }
131 } 132 }
132 133
133 void EventConverterEvdevImpl::ConvertMouseMoveEvent(const input_event& input) { 134 void EventConverterEvdevImpl::ConvertMouseMoveEvent(const input_event& input) {
134 if (!cursor_) 135 if (!cursor_)
135 return; 136 return;
136 switch (input.code) { 137 switch (input.code) {
137 case REL_X: 138 case REL_X:
138 x_offset_ = input.value; 139 x_offset_ = input.value;
139 break; 140 break;
140 case REL_Y: 141 case REL_Y:
141 y_offset_ = input.value; 142 y_offset_ = input.value;
142 break; 143 break;
143 } 144 }
144 } 145 }
145 146
147 void EventConverterEvdevImpl::OnKeyChange(unsigned int key,
148 bool down,
149 const base::TimeDelta& timestamp) {
150 if (key > KEY_MAX)
151 return;
152
153 if (down == key_state_.test(key))
154 return;
155
156 // Apply key filter (releases for previously pressed keys are excepted).
157 DomCode key_code =
158 KeycodeConverter::NativeKeycodeToDomCode(EvdevCodeToNativeCode(key));
159 if (down && allowed_keys_ && allowed_keys_->count(key_code))
160 return;
161
162 // State transition: !(down) -> (down)
163 if (down)
164 key_state_.set(key);
165 else
166 key_state_.reset(key);
167
168 dispatcher_->DispatchKeyEvent(KeyEventParams(id_, key, down, timestamp));
169 }
170
171 void EventConverterEvdevImpl::ReleaseKeys() {
172 base::TimeDelta timestamp = ui::EventTimeForNow();
173 for (int key = 0; key < KEY_CNT; ++key)
174 OnKeyChange(key, false /* down */, timestamp);
175 }
176
177 void EventConverterEvdevImpl::OnLostSync() {
178 LOG(WARNING) << "kernel dropped input events";
179
180 // We may have missed key releases. Release everything.
181 // TODO(spang): Use EVIOCGKEY to avoid releasing keys that are still held.
182 ReleaseKeys();
183 }
184
146 void EventConverterEvdevImpl::DispatchMouseButton(const input_event& input) { 185 void EventConverterEvdevImpl::DispatchMouseButton(const input_event& input) {
147 if (!cursor_) 186 if (!cursor_)
148 return; 187 return;
149 188
150 dispatcher_->DispatchMouseButtonEvent(MouseButtonEventParams( 189 dispatcher_->DispatchMouseButtonEvent(MouseButtonEventParams(
151 id_, cursor_->GetLocation(), input.code, input.value, 190 id_, cursor_->GetLocation(), input.code, input.value,
152 /* allow_remap */ true, TimeDeltaFromInputEvent(input))); 191 /* allow_remap */ true, TimeDeltaFromInputEvent(input)));
153 } 192 }
154 193
155 void EventConverterEvdevImpl::FlushEvents(const input_event& input) { 194 void EventConverterEvdevImpl::FlushEvents(const input_event& input) {
156 if (!cursor_ || (x_offset_ == 0 && y_offset_ == 0)) 195 if (!cursor_ || (x_offset_ == 0 && y_offset_ == 0))
157 return; 196 return;
158 197
159 cursor_->MoveCursor(gfx::Vector2dF(x_offset_, y_offset_)); 198 cursor_->MoveCursor(gfx::Vector2dF(x_offset_, y_offset_));
160 199
161 dispatcher_->DispatchMouseMoveEvent(MouseMoveEventParams( 200 dispatcher_->DispatchMouseMoveEvent(MouseMoveEventParams(
162 id_, cursor_->GetLocation(), TimeDeltaFromInputEvent(input))); 201 id_, cursor_->GetLocation(), TimeDeltaFromInputEvent(input)));
163 202
164 x_offset_ = 0; 203 x_offset_ = 0;
165 y_offset_ = 0; 204 y_offset_ = 0;
166 } 205 }
167 206
168 } // namespace ui 207 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/ozone/evdev/event_converter_evdev_impl.h ('k') | ui/events/ozone/evdev/event_converter_evdev_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698