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

Side by Side Diff: chrome/browser/chromeos/events/event_rewriter.cc

Issue 336403005: Use XInput2 events for keyboard events. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address review comments (derat). Created 6 years, 6 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 "chrome/browser/chromeos/events/event_rewriter.h" 5 #include "chrome/browser/chromeos/events/event_rewriter.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "ash/sticky_keys/sticky_keys_controller.h" 9 #include "ash/sticky_keys/sticky_keys_controller.h"
10 #include "ash/wm/window_state.h" 10 #include "ash/wm/window_state.h"
11 #include "ash/wm/window_util.h" 11 #include "ash/wm/window_util.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "base/prefs/pref_service.h" 15 #include "base/prefs/pref_service.h"
16 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
17 #include "base/sys_info.h" 17 #include "base/sys_info.h"
18 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h" 18 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
19 #include "chrome/browser/chromeos/login/users/user_manager.h" 19 #include "chrome/browser/chromeos/login/users/user_manager.h"
20 #include "chrome/browser/profiles/profile_manager.h" 20 #include "chrome/browser/profiles/profile_manager.h"
21 #include "chrome/common/pref_names.h" 21 #include "chrome/common/pref_names.h"
22 #include "chromeos/chromeos_switches.h" 22 #include "chromeos/chromeos_switches.h"
23 #include "chromeos/ime/ime_keyboard.h" 23 #include "chromeos/ime/ime_keyboard.h"
24 #include "chromeos/ime/input_method_manager.h" 24 #include "chromeos/ime/input_method_manager.h"
25 #include "ui/events/event.h" 25 #include "ui/events/event.h"
26 #include "ui/events/event_utils.h" 26 #include "ui/events/event_utils.h"
27 #include "ui/events/keycodes/keyboard_code_conversion.h" 27 #include "ui/events/keycodes/keyboard_code_conversion.h"
28 #include "ui/events/platform/platform_event_source.h"
29 #include "ui/wm/core/window_util.h" 28 #include "ui/wm/core/window_util.h"
30 29
31 #if defined(USE_X11) 30 #if defined(USE_X11)
32 #include <X11/extensions/XInput2.h> 31 #include <X11/extensions/XInput2.h>
33 #include <X11/Xlib.h> 32 #include <X11/Xlib.h>
34 // Get rid of macros from Xlib.h that conflicts with other parts of the code. 33 // Get rid of macros from Xlib.h that conflicts with other parts of the code.
35 #undef RootWindow 34 #undef RootWindow
36 #undef Status 35 #undef Status
37 36
38 #include "chrome/browser/chromeos/events/xinput_hierarchy_changed_event_listener .h"
39 #include "ui/base/x/x11_util.h" 37 #include "ui/base/x/x11_util.h"
40 #include "ui/events/keycodes/keyboard_code_conversion_x.h" 38 #include "ui/events/keycodes/keyboard_code_conversion_x.h"
41 #endif 39 #endif
42 40
43 namespace chromeos { 41 namespace chromeos {
44 42
45 namespace { 43 namespace {
46 44
47 const int kBadDeviceId = -1;
48
49 // Table of key properties of remappable keys and/or remapping targets. 45 // Table of key properties of remappable keys and/or remapping targets.
50 // This is searched in two distinct ways: 46 // This is searched in two distinct ways:
51 // - |remap_to| is an |input_method::ModifierKey|, which is the form 47 // - |remap_to| is an |input_method::ModifierKey|, which is the form
52 // held in user preferences. |GetRemappedKey()| maps this to the 48 // held in user preferences. |GetRemappedKey()| maps this to the
53 // corresponding |key_code| and characterstic event |flag|. 49 // corresponding |key_code| and characterstic event |flag|.
54 // - |flag| is a |ui::EventFlags|. |GetRemappedModifierMasks()| maps this 50 // - |flag| is a |ui::EventFlags|. |GetRemappedModifierMasks()| maps this
55 // to the corresponding user preference |pref_name| for that flag's 51 // to the corresponding user preference |pref_name| for that flag's
56 // key, so that it can then be remapped as above. 52 // key, so that it can then be remapped as above.
57 // In addition |kModifierRemappingCtrl| is a direct reference to the 53 // In addition |kModifierRemappingCtrl| is a direct reference to the
58 // Control key entry in the table, used in handling Chromebook Diamond 54 // Control key entry in the table, used in handling Chromebook Diamond
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 {ui::EF_MIDDLE_MOUSE_BUTTON, Button2Mask}, 142 {ui::EF_MIDDLE_MOUSE_BUTTON, Button2Mask},
147 {ui::EF_RIGHT_MOUSE_BUTTON, Button3Mask}, 143 {ui::EF_RIGHT_MOUSE_BUTTON, Button3Mask},
148 }; 144 };
149 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(flags); ++i) { 145 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(flags); ++i) {
150 if (ui_flags & flags[i].ui) 146 if (ui_flags & flags[i].ui)
151 *x_flags |= flags[i].x; 147 *x_flags |= flags[i].x;
152 else 148 else
153 *x_flags &= ~flags[i].x; 149 *x_flags &= ~flags[i].x;
154 } 150 }
155 } 151 }
152
153 void UpdateX11Button(int ui_flag, unsigned int* x_button) {
154 switch (ui_flag) {
155 case ui::EF_LEFT_MOUSE_BUTTON:
156 *x_button = Button1;
157 break;
158 case ui::EF_MIDDLE_MOUSE_BUTTON:
159 *x_button = Button2;
160 break;
161 case ui::EF_RIGHT_MOUSE_BUTTON:
162 *x_button = Button3;
163 break;
164 }
165 }
156 #endif 166 #endif
157 167
158 bool IsSendEvent(const ui::Event& event) { 168 bool IsSendEvent(const ui::Event& event) {
159 #if defined(USE_X11) 169 #if defined(USE_X11)
160 // Do not rewrite an event sent by ui_controls::SendKeyPress(). See 170 // Do not rewrite an event sent by ui_controls::SendKeyPress(). See
161 // crbug.com/136465. 171 // crbug.com/136465.
162 XEvent* xev = event.native_event(); 172 XEvent* xev = event.native_event();
163 if (xev && xev->xany.send_event) 173 if (xev && xev->xany.send_event)
164 return true; 174 return true;
165 #endif 175 #endif
166 return false; 176 return false;
167 } 177 }
168 178
169 } // namespace 179 } // namespace
170 180
171 EventRewriter::EventRewriter(ash::StickyKeysController* sticky_keys_controller) 181 EventRewriter::EventRewriter(ash::StickyKeysController* sticky_keys_controller)
172 : last_device_id_(kBadDeviceId), 182 : last_keyboard_device_id_(ui::ED_UNKNOWN_DEVICE),
173 ime_keyboard_for_testing_(NULL), 183 ime_keyboard_for_testing_(NULL),
174 pref_service_for_testing_(NULL), 184 pref_service_for_testing_(NULL),
175 sticky_keys_controller_(sticky_keys_controller) { 185 sticky_keys_controller_(sticky_keys_controller) {
176 #if defined(USE_X11)
177 ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
178 if (base::SysInfo::IsRunningOnChromeOS()) {
179 XInputHierarchyChangedEventListener::GetInstance()->AddObserver(this);
180 }
181 #endif
182 } 186 }
183 187
184 EventRewriter::~EventRewriter() { 188 EventRewriter::~EventRewriter() {
185 #if defined(USE_X11)
186 ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
187 if (base::SysInfo::IsRunningOnChromeOS()) {
188 XInputHierarchyChangedEventListener::GetInstance()->RemoveObserver(this);
189 }
190 #endif
191 } 189 }
192 190
193 EventRewriter::DeviceType EventRewriter::DeviceAddedForTesting( 191 EventRewriter::DeviceType EventRewriter::KeyboardDeviceAddedForTesting(
194 int device_id, 192 int device_id,
195 const std::string& device_name) { 193 const std::string& device_name) {
196 return DeviceAddedInternal(device_id, device_name); 194 // Tests must avoid XI2 reserved device IDs.
195 DCHECK((device_id < 0) || (device_id > 1));
196 return KeyboardDeviceAddedInternal(device_id, device_name);
197 } 197 }
198 198
199 void EventRewriter::RewriteLocatedEventForTesting(const ui::Event& event, 199 void EventRewriter::RewriteMouseButtonEventForTesting(
200 int* flags) { 200 const ui::MouseEvent& event,
201 RewriteLocatedEvent(event, flags); 201 scoped_ptr<ui::Event>* rewritten_event) {
202 RewriteMouseButtonEvent(event, rewritten_event);
202 } 203 }
203 204
204 ui::EventRewriteStatus EventRewriter::RewriteEvent( 205 ui::EventRewriteStatus EventRewriter::RewriteEvent(
205 const ui::Event& event, 206 const ui::Event& event,
206 scoped_ptr<ui::Event>* rewritten_event) { 207 scoped_ptr<ui::Event>* rewritten_event) {
207 if ((event.type() == ui::ET_KEY_PRESSED) || 208 if ((event.type() == ui::ET_KEY_PRESSED) ||
208 (event.type() == ui::ET_KEY_RELEASED)) { 209 (event.type() == ui::ET_KEY_RELEASED)) {
209 return RewriteKeyEvent(static_cast<const ui::KeyEvent&>(event), 210 return RewriteKeyEvent(static_cast<const ui::KeyEvent&>(event),
210 rewritten_event); 211 rewritten_event);
211 } 212 }
(...skipping 26 matching lines...) Expand all
238 // modifier key releases that match the ones previously discarded. So, we 239 // modifier key releases that match the ones previously discarded. So, we
239 // know that they don't have to be passed through the post-sticky key 240 // know that they don't have to be passed through the post-sticky key
240 // rewriting phases, |RewriteExtendedKeys()| and |RewriteFunctionKeys()|, 241 // rewriting phases, |RewriteExtendedKeys()| and |RewriteFunctionKeys()|,
241 // because those phases do nothing with modifier key releases. 242 // because those phases do nothing with modifier key releases.
242 return sticky_keys_controller_->NextDispatchEvent(new_event); 243 return sticky_keys_controller_->NextDispatchEvent(new_event);
243 } 244 }
244 NOTREACHED(); 245 NOTREACHED();
245 return ui::EVENT_REWRITE_CONTINUE; 246 return ui::EVENT_REWRITE_CONTINUE;
246 } 247 }
247 248
249 void EventRewriter::BuildRewrittenKeyEvent(
250 const ui::KeyEvent& key_event,
251 ui::KeyboardCode key_code,
252 int flags,
253 scoped_ptr<ui::Event>* rewritten_event) {
254 ui::KeyEvent* rewritten_key_event = 0;
Daniel Erat 2014/06/25 20:06:13 nit: this should still be NULL
kpschoedel 2014/06/25 21:10:40 Done.
248 #if defined(USE_X11) 255 #if defined(USE_X11)
256 XEvent* xev = key_event.native_event();
257 if (xev) {
258 XEvent xkeyevent;
259 // Convert all XI2-based key events into X11 core-based key events,
260 // until consumers no longer depend on receiving X11 core events.
261 if (xev->type == GenericEvent)
262 ui::InitXKeyEventFromXIDeviceEvent(*xev, &xkeyevent);
263 else
264 xkeyevent.xkey = xev->xkey;
265
266 // Update native event to match rewritten |ui::Event|.
267 xkeyevent.xkey.keycode = XKeysymToKeycode(
268 gfx::GetXDisplay(),
269 ui::XKeysymForWindowsKeyCode(key_code, flags & ui::EF_SHIFT_DOWN));
270 UpdateX11EventMask(flags, &xkeyevent.xkey.state);
271 ui::KeyEvent x11_key_event(&xkeyevent, false);
272 rewritten_key_event = new ui::KeyEvent(x11_key_event);
273 }
274 #endif
275 if (!rewritten_key_event)
276 rewritten_key_event = new ui::KeyEvent(key_event);
277 rewritten_key_event->set_flags(flags);
278 rewritten_key_event->set_key_code(key_code);
279 rewritten_key_event->set_character(
280 ui::GetCharacterFromKeyCode(key_code, flags));
281 rewritten_key_event->NormalizeFlags();
282 rewritten_event->reset(rewritten_key_event);
283 }
284
249 void EventRewriter::DeviceKeyPressedOrReleased(int device_id) { 285 void EventRewriter::DeviceKeyPressedOrReleased(int device_id) {
250 if (!device_id_to_type_.count(device_id)) { 286 if (!device_id_to_type_.count(device_id))
251 // |device_id| is unknown. This means the device was connected before 287 KeyboardDeviceAdded(device_id);
252 // booting the OS. Query the name of the device and add it to the map. 288 last_keyboard_device_id_ = device_id;
253 DeviceAdded(device_id);
254 }
255 last_device_id_ = device_id;
256 } 289 }
257 #endif
258 290
259 const PrefService* EventRewriter::GetPrefService() const { 291 const PrefService* EventRewriter::GetPrefService() const {
260 if (pref_service_for_testing_) 292 if (pref_service_for_testing_)
261 return pref_service_for_testing_; 293 return pref_service_for_testing_;
262 Profile* profile = ProfileManager::GetActiveUserProfile(); 294 Profile* profile = ProfileManager::GetActiveUserProfile();
263 return profile ? profile->GetPrefs() : NULL; 295 return profile ? profile->GetPrefs() : NULL;
264 } 296 }
265 297
266 bool EventRewriter::IsAppleKeyboard() const { 298 bool EventRewriter::IsAppleKeyboard() const {
267 if (last_device_id_ == kBadDeviceId) 299 if (last_keyboard_device_id_ == ui::ED_UNKNOWN_DEVICE)
268 return false; 300 return false;
269 301
270 // Check which device generated |event|. 302 // Check which device generated |event|.
271 std::map<int, DeviceType>::const_iterator iter = 303 std::map<int, DeviceType>::const_iterator iter =
272 device_id_to_type_.find(last_device_id_); 304 device_id_to_type_.find(last_keyboard_device_id_);
273 if (iter == device_id_to_type_.end()) { 305 if (iter == device_id_to_type_.end()) {
274 LOG(ERROR) << "Device ID " << last_device_id_ << " is unknown."; 306 LOG(ERROR) << "Device ID " << last_keyboard_device_id_ << " is unknown.";
275 return false; 307 return false;
276 } 308 }
277 309
278 const DeviceType type = iter->second; 310 const DeviceType type = iter->second;
279 return type == kDeviceAppleKeyboard; 311 return type == kDeviceAppleKeyboard;
280 } 312 }
281 313
282 bool EventRewriter::TopRowKeysAreFunctionKeys(const ui::KeyEvent& event) const { 314 bool EventRewriter::TopRowKeysAreFunctionKeys(const ui::KeyEvent& event) const {
283 const PrefService* prefs = GetPrefService(); 315 const PrefService* prefs = GetPrefService();
284 if (prefs && prefs->FindPreference(prefs::kLanguageSendFunctionKeys) && 316 if (prefs && prefs->FindPreference(prefs::kLanguageSendFunctionKeys) &&
285 prefs->GetBoolean(prefs::kLanguageSendFunctionKeys)) 317 prefs->GetBoolean(prefs::kLanguageSendFunctionKeys))
286 return true; 318 return true;
287 319
288 ash::wm::WindowState* state = ash::wm::GetActiveWindowState(); 320 ash::wm::WindowState* state = ash::wm::GetActiveWindowState();
289 return state ? state->top_row_keys_are_function_keys() : false; 321 return state ? state->top_row_keys_are_function_keys() : false;
290 } 322 }
291 323
292 int EventRewriter::GetRemappedModifierMasks(const PrefService& pref_service, 324 int EventRewriter::GetRemappedModifierMasks(const PrefService& pref_service,
293 const ui::Event& event, 325 const ui::Event& event,
294 int original_flags) const { 326 int original_flags) const {
295 int unmodified_flags = original_flags; 327 int unmodified_flags = original_flags;
296 int rewritten_flags = 0; 328 int rewritten_flags = 0;
297 for (size_t i = 0; unmodified_flags && (i < arraysize(kModifierRemappings)); 329 for (size_t i = 0; unmodified_flags && (i < arraysize(kModifierRemappings));
298 ++i) { 330 ++i) {
299 const ModifierRemapping* remapped_key = 0; 331 const ModifierRemapping* remapped_key = NULL;
300 if (!(unmodified_flags & kModifierRemappings[i].flag)) 332 if (!(unmodified_flags & kModifierRemappings[i].flag))
301 continue; 333 continue;
302 switch (kModifierRemappings[i].flag) { 334 switch (kModifierRemappings[i].flag) {
303 case ui::EF_COMMAND_DOWN: 335 case ui::EF_COMMAND_DOWN:
304 // Rewrite Command key presses on an Apple keyboard to Control. 336 // Rewrite Command key presses on an Apple keyboard to Control.
305 if (IsAppleKeyboard()) { 337 if (IsAppleKeyboard()) {
306 DCHECK_EQ(ui::EF_CONTROL_DOWN, kModifierRemappingCtrl->flag); 338 DCHECK_EQ(ui::EF_CONTROL_DOWN, kModifierRemappingCtrl->flag);
307 remapped_key = kModifierRemappingCtrl; 339 remapped_key = kModifierRemappingCtrl;
308 } 340 }
309 break; 341 break;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 remapped_state->key_code = map.output_key_code; 379 remapped_state->key_code = map.output_key_code;
348 remapped_state->flags = (input.flags & ~map.input_flags) | map.output_flags; 380 remapped_state->flags = (input.flags & ~map.input_flags) | map.output_flags;
349 return true; 381 return true;
350 } 382 }
351 return false; 383 return false;
352 } 384 }
353 385
354 ui::EventRewriteStatus EventRewriter::RewriteKeyEvent( 386 ui::EventRewriteStatus EventRewriter::RewriteKeyEvent(
355 const ui::KeyEvent& key_event, 387 const ui::KeyEvent& key_event,
356 scoped_ptr<ui::Event>* rewritten_event) { 388 scoped_ptr<ui::Event>* rewritten_event) {
389 if (key_event.source_device_id() != ui::ED_UNKNOWN_DEVICE)
390 DeviceKeyPressedOrReleased(key_event.source_device_id());
357 MutableKeyState state = {key_event.flags(), key_event.key_code()}; 391 MutableKeyState state = {key_event.flags(), key_event.key_code()};
358 bool is_send_event = IsSendEvent(key_event); 392 bool is_send_event = IsSendEvent(key_event);
359 if (!is_send_event) { 393 if (!is_send_event) {
360 RewriteModifierKeys(key_event, &state); 394 RewriteModifierKeys(key_event, &state);
361 RewriteNumPadKeys(key_event, &state); 395 RewriteNumPadKeys(key_event, &state);
362 } 396 }
363 ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE; 397 ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE;
364 if (sticky_keys_controller_) { 398 if (sticky_keys_controller_) {
365 status = sticky_keys_controller_->RewriteKeyEvent( 399 status = sticky_keys_controller_->RewriteKeyEvent(
366 key_event, state.key_code, &state.flags); 400 key_event, state.key_code, &state.flags);
367 if (status == ui::EVENT_REWRITE_DISCARD) 401 if (status == ui::EVENT_REWRITE_DISCARD)
368 return ui::EVENT_REWRITE_DISCARD; 402 return ui::EVENT_REWRITE_DISCARD;
369 } 403 }
370 if (!is_send_event) { 404 if (!is_send_event) {
371 RewriteExtendedKeys(key_event, &state); 405 RewriteExtendedKeys(key_event, &state);
372 RewriteFunctionKeys(key_event, &state); 406 RewriteFunctionKeys(key_event, &state);
373 } 407 }
374 if ((key_event.flags() == state.flags) && 408 if ((key_event.flags() == state.flags) &&
375 (key_event.key_code() == state.key_code) && 409 (key_event.key_code() == state.key_code) &&
410 #if defined(USE_X11)
411 // TODO(kpschoedel): This test is present because several consumers of
412 // key events depend on having a native core X11 event, so we rewrite
413 // all XI2 key events (GenericEvent) into corresponding core X11 key
414 // events. Remove this when event consumers no longer care about
415 // native X11 event details (crbug.com/380349).
416 (!key_event.HasNativeEvent() ||
417 (key_event.native_event()->type != GenericEvent)) &&
418 #endif
376 (status == ui::EVENT_REWRITE_CONTINUE)) { 419 (status == ui::EVENT_REWRITE_CONTINUE)) {
377 return ui::EVENT_REWRITE_CONTINUE; 420 return ui::EVENT_REWRITE_CONTINUE;
378 } 421 }
379 // Sticky keys may have returned a result other than |EVENT_REWRITE_CONTINUE|, 422 // Sticky keys may have returned a result other than |EVENT_REWRITE_CONTINUE|,
380 // in which case we need to preserve that return status. Alternatively, we 423 // in which case we need to preserve that return status. Alternatively, we
381 // might be here because key_event changed, in which case we need to return 424 // might be here because key_event changed, in which case we need to
382 // |EVENT_REWRITE_REWRITTEN|. 425 // return |EVENT_REWRITE_REWRITTEN|.
383 if (status == ui::EVENT_REWRITE_CONTINUE) 426 if (status == ui::EVENT_REWRITE_CONTINUE)
384 status = ui::EVENT_REWRITE_REWRITTEN; 427 status = ui::EVENT_REWRITE_REWRITTEN;
385 ui::KeyEvent* rewritten_key_event = new ui::KeyEvent(key_event); 428 BuildRewrittenKeyEvent(
386 rewritten_event->reset(rewritten_key_event); 429 key_event, state.key_code, state.flags, rewritten_event);
387 rewritten_key_event->set_flags(state.flags);
388 rewritten_key_event->set_key_code(state.key_code);
389 rewritten_key_event->set_character(
390 ui::GetCharacterFromKeyCode(state.key_code, state.flags));
391 rewritten_key_event->NormalizeFlags();
392 #if defined(USE_X11)
393 XEvent* xev = rewritten_key_event->native_event();
394 if (xev) {
395 CHECK(xev->type == KeyPress || xev->type == KeyRelease);
396 XKeyEvent* xkey = &(xev->xkey);
397 UpdateX11EventMask(rewritten_key_event->flags(), &xkey->state);
398 xkey->keycode =
399 XKeysymToKeycode(gfx::GetXDisplay(),
400 ui::XKeysymForWindowsKeyCode(
401 state.key_code, state.flags & ui::EF_SHIFT_DOWN));
402 }
403 #endif
404 return status; 430 return status;
405 } 431 }
406 432
407 ui::EventRewriteStatus EventRewriter::RewriteMouseButtonEvent( 433 ui::EventRewriteStatus EventRewriter::RewriteMouseButtonEvent(
408 const ui::MouseEvent& mouse_event, 434 const ui::MouseEvent& mouse_event,
409 scoped_ptr<ui::Event>* rewritten_event) { 435 scoped_ptr<ui::Event>* rewritten_event) {
410 int flags = mouse_event.flags(); 436 int flags = mouse_event.flags();
411 RewriteLocatedEvent(mouse_event, &flags); 437 RewriteLocatedEvent(mouse_event, &flags);
412 ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE; 438 ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE;
413 if (sticky_keys_controller_) 439 if (sticky_keys_controller_)
414 status = sticky_keys_controller_->RewriteMouseEvent(mouse_event, &flags); 440 status = sticky_keys_controller_->RewriteMouseEvent(mouse_event, &flags);
441 int changed_button = ui::EF_NONE;
442 if ((mouse_event.type() == ui::ET_MOUSE_PRESSED) ||
443 (mouse_event.type() == ui::ET_MOUSE_RELEASED)) {
444 changed_button = RewriteModifierClick(mouse_event, &flags);
445 }
415 if ((mouse_event.flags() == flags) && 446 if ((mouse_event.flags() == flags) &&
416 (status == ui::EVENT_REWRITE_CONTINUE)) { 447 (status == ui::EVENT_REWRITE_CONTINUE)) {
417 return ui::EVENT_REWRITE_CONTINUE; 448 return ui::EVENT_REWRITE_CONTINUE;
418 } 449 }
419 if (status == ui::EVENT_REWRITE_CONTINUE) 450 if (status == ui::EVENT_REWRITE_CONTINUE)
420 status = ui::EVENT_REWRITE_REWRITTEN; 451 status = ui::EVENT_REWRITE_REWRITTEN;
421 ui::MouseEvent* rewritten_mouse_event = new ui::MouseEvent(mouse_event); 452 ui::MouseEvent* rewritten_mouse_event = new ui::MouseEvent(mouse_event);
422 rewritten_event->reset(rewritten_mouse_event); 453 rewritten_event->reset(rewritten_mouse_event);
423 rewritten_mouse_event->set_flags(flags); 454 rewritten_mouse_event->set_flags(flags);
455 if (changed_button != ui::EF_NONE)
456 rewritten_mouse_event->set_changed_button_flags(changed_button);
424 #if defined(USE_X11) 457 #if defined(USE_X11)
425 XEvent* xev = rewritten_mouse_event->native_event(); 458 XEvent* xev = rewritten_mouse_event->native_event();
426 if (xev) { 459 if (xev) {
427 switch (xev->type) { 460 switch (xev->type) {
428 case ButtonPress: 461 case ButtonPress:
429 case ButtonRelease: { 462 case ButtonRelease: {
430 XButtonEvent* xbutton = &(xev->xbutton); 463 XButtonEvent* xbutton = &(xev->xbutton);
431 UpdateX11EventMask(rewritten_mouse_event->flags(), &xbutton->state); 464 UpdateX11EventMask(rewritten_mouse_event->flags(), &xbutton->state);
465 if (changed_button)
466 UpdateX11Button(changed_button, &xbutton->button);
432 break; 467 break;
433 } 468 }
434 case GenericEvent: { 469 case GenericEvent: {
435 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); 470 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data);
436 CHECK(xievent->evtype == XI_ButtonPress || 471 CHECK(xievent->evtype == XI_ButtonPress ||
437 xievent->evtype == XI_ButtonRelease); 472 xievent->evtype == XI_ButtonRelease);
438 UpdateX11EventMask( 473 UpdateX11EventMask(
439 rewritten_mouse_event->flags(), 474 rewritten_mouse_event->flags(),
440 reinterpret_cast<unsigned int*>(&xievent->mods.effective)); 475 reinterpret_cast<unsigned int*>(&xievent->mods.effective));
476 if (changed_button) {
477 UpdateX11Button(changed_button,
478 reinterpret_cast<unsigned int*>(&xievent->detail));
479 }
441 break; 480 break;
442 } 481 }
443 default: 482 default:
444 NOTREACHED(); 483 NOTREACHED();
445 } 484 }
446 } 485 }
447 #endif 486 #endif
448 return status; 487 return status;
449 } 488 }
450 489
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
829 rewritten = RewriteWithKeyboardRemappingsByKeyCode( 868 rewritten = RewriteWithKeyboardRemappingsByKeyCode(
830 kNumberKeysToFkeys, arraysize(kNumberKeysToFkeys), incoming, state); 869 kNumberKeysToFkeys, arraysize(kNumberKeysToFkeys), incoming, state);
831 } 870 }
832 } 871 }
833 872
834 void EventRewriter::RewriteLocatedEvent(const ui::Event& event, 873 void EventRewriter::RewriteLocatedEvent(const ui::Event& event,
835 int* flags) { 874 int* flags) {
836 const PrefService* pref_service = GetPrefService(); 875 const PrefService* pref_service = GetPrefService();
837 if (!pref_service) 876 if (!pref_service)
838 return; 877 return;
839
840 // First, remap modifier masks.
841 *flags = GetRemappedModifierMasks(*pref_service, event, *flags); 878 *flags = GetRemappedModifierMasks(*pref_service, event, *flags);
842
843 #if defined(USE_X11)
844 // TODO(kpschoedel): de-X11 with unified device ids from crbug.com/360377
845 XEvent* xevent = event.native_event();
846 if (!xevent || xevent->type != GenericEvent)
847 return;
848 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xevent->xcookie.data);
849 if (xievent->evtype != XI_ButtonPress && xievent->evtype != XI_ButtonRelease)
850 return;
851 UpdateX11EventMask(*flags,
852 reinterpret_cast<unsigned int*>(&xievent->mods.effective));
853
854 // Then, remap Alt+Button1 to Button3.
855 if ((xievent->evtype == XI_ButtonPress ||
856 pressed_device_ids_.count(xievent->sourceid)) &&
857 (xievent->mods.effective & Mod1Mask) && xievent->detail == Button1) {
858 *flags &= ~(ui::EF_ALT_DOWN | ui::EF_LEFT_MOUSE_BUTTON);
859 *flags |= ui::EF_RIGHT_MOUSE_BUTTON;
860 xievent->mods.effective &= ~Mod1Mask;
861 xievent->detail = Button3;
862 if (xievent->evtype == XI_ButtonRelease) {
863 // On the release clear the left button from the existing state and the
864 // mods, and set the right button.
865 XISetMask(xievent->buttons.mask, Button3);
866 XIClearMask(xievent->buttons.mask, Button1);
867 xievent->mods.effective &= ~Button1Mask;
868 pressed_device_ids_.erase(xievent->sourceid);
869 } else {
870 pressed_device_ids_.insert(xievent->sourceid);
871 }
872 }
873 #endif // defined(USE_X11)
874 } 879 }
875 880
876 EventRewriter::DeviceType EventRewriter::DeviceAddedInternal( 881 int EventRewriter::RewriteModifierClick(const ui::MouseEvent& mouse_event,
882 int* flags) {
883 // Remap Alt+Button1 to Button3.
884 const int kAltLeftButton = (ui::EF_ALT_DOWN | ui::EF_LEFT_MOUSE_BUTTON);
885 if (((*flags & kAltLeftButton) == kAltLeftButton) &&
886 ((mouse_event.type() == ui::ET_MOUSE_PRESSED) ||
887 pressed_device_ids_.count(mouse_event.source_device_id()))) {
888 *flags &= ~kAltLeftButton;
889 *flags |= ui::EF_RIGHT_MOUSE_BUTTON;
890 if (mouse_event.type() == ui::ET_MOUSE_PRESSED)
891 pressed_device_ids_.insert(mouse_event.source_device_id());
892 else
893 pressed_device_ids_.erase(mouse_event.source_device_id());
894 return ui::EF_RIGHT_MOUSE_BUTTON;
895 }
896 return ui::EF_NONE;
897 }
898
899 EventRewriter::DeviceType EventRewriter::KeyboardDeviceAddedInternal(
877 int device_id, 900 int device_id,
878 const std::string& device_name) { 901 const std::string& device_name) {
879 const DeviceType type = GetDeviceType(device_name); 902 const DeviceType type = GetDeviceType(device_name);
880 if (type == kDeviceAppleKeyboard) { 903 if (type == kDeviceAppleKeyboard) {
881 VLOG(1) << "Apple keyboard '" << device_name << "' connected: " 904 VLOG(1) << "Apple keyboard '" << device_name << "' connected: "
882 << "id=" << device_id; 905 << "id=" << device_id;
883 } 906 }
884 // Always overwrite the existing device_id since the X server may reuse a 907 // Always overwrite the existing device_id since the X server may reuse a
885 // device id for an unattached device. 908 // device id for an unattached device.
886 device_id_to_type_[device_id] = type; 909 device_id_to_type_[device_id] = type;
887 return type; 910 return type;
888 } 911 }
889 912
913 void EventRewriter::KeyboardDeviceAdded(int device_id) {
890 #if defined(USE_X11) 914 #if defined(USE_X11)
891 void EventRewriter::WillProcessEvent(const ui::PlatformEvent& event) {
892 XEvent* xevent = event;
893 if (xevent->type == GenericEvent) {
894 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xevent->xcookie.data);
895 if (xievent->evtype == XI_KeyPress || xievent->evtype == XI_KeyRelease) {
896 if (xievent->deviceid == xievent->sourceid)
897 DeviceKeyPressedOrReleased(xievent->deviceid);
898 }
899 }
900 }
901
902 void EventRewriter::DidProcessEvent(const ui::PlatformEvent& event) {
903 }
904
905 void EventRewriter::DeviceHierarchyChanged() {
906 }
907
908 void EventRewriter::DeviceAdded(int device_id) {
909 DCHECK_NE(XIAllDevices, device_id); 915 DCHECK_NE(XIAllDevices, device_id);
910 DCHECK_NE(XIAllMasterDevices, device_id); 916 DCHECK_NE(XIAllMasterDevices, device_id);
911 if (device_id == XIAllDevices || device_id == XIAllMasterDevices) { 917 if (device_id == XIAllDevices || device_id == XIAllMasterDevices) {
912 LOG(ERROR) << "Unexpected device_id passed: " << device_id; 918 LOG(ERROR) << "Unexpected device_id passed: " << device_id;
913 return; 919 return;
914 } 920 }
915 921
916 int ndevices_return = 0; 922 int ndevices_return = 0;
917 XIDeviceInfo* device_info = 923 XIDeviceInfo* device_info =
918 XIQueryDevice(gfx::GetXDisplay(), device_id, &ndevices_return); 924 XIQueryDevice(gfx::GetXDisplay(), device_id, &ndevices_return);
919 925
920 // Since |device_id| is neither XIAllDevices nor XIAllMasterDevices, 926 // Since |device_id| is neither XIAllDevices nor XIAllMasterDevices,
921 // the number of devices found should be either 0 (not found) or 1. 927 // the number of devices found should be either 0 (not found) or 1.
922 if (!device_info) { 928 if (!device_info) {
923 LOG(ERROR) << "XIQueryDevice: Device ID " << device_id << " is unknown."; 929 LOG(ERROR) << "XIQueryDevice: Device ID " << device_id << " is unknown.";
924 return; 930 return;
925 } 931 }
926 932
927 DCHECK_EQ(1, ndevices_return); 933 DCHECK_EQ(1, ndevices_return);
928 for (int i = 0; i < ndevices_return; ++i) { 934 for (int i = 0; i < ndevices_return; ++i) {
929 DCHECK_EQ(device_id, device_info[i].deviceid); // see the comment above. 935 DCHECK_EQ(device_id, device_info[i].deviceid); // see the comment above.
930 DCHECK(device_info[i].name); 936 DCHECK(device_info[i].name);
931 DeviceAddedInternal(device_info[i].deviceid, device_info[i].name); 937 KeyboardDeviceAddedInternal(device_info[i].deviceid, device_info[i].name);
932 } 938 }
933 939
934 XIFreeDeviceInfo(device_info); 940 XIFreeDeviceInfo(device_info);
941 #else
942 KeyboardDeviceAddedInternal(device_id, "keyboard");
943 #endif
935 } 944 }
936 945
937 void EventRewriter::DeviceRemoved(int device_id) {
938 device_id_to_type_.erase(device_id);
939 }
940 #endif
941
942 } // namespace chromeos 946 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698