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

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: Add TODO regarding XI2-to-core rewriting. 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::RewrittenKeyEvent(const ui::KeyEvent& key_event,
250 ui::KeyboardCode key_code,
251 int flags,
252 scoped_ptr<ui::Event>* rewritten_event) {
253 ui::KeyEvent* rewritten_key_event = 0;
Daniel Erat 2014/06/25 17:13:24 nit: initialize to NULL instead of 0
kpschoedel 2014/06/25 19:59:48 Done.
248 #if defined(USE_X11) 254 #if defined(USE_X11)
255 XEvent* xev = key_event.native_event();
256 if (xev) {
257 XEvent xkeyevent;
258 // Convert all XI2-based key events into X11 core-based key events,
259 // until consumers no longer depend on receiving X11 core events.
260 if (xev->type == GenericEvent)
261 ui::InitXKeyEventFromXIDeviceEvent(*xev, &xkeyevent);
262 else
263 xkeyevent.xkey = xev->xkey;
Daniel Erat 2014/06/25 17:13:24 nit: mind adding a blank line after this one to se
kpschoedel 2014/06/25 19:59:48 Done.
264 // Update native event to match rewritten |ui::Event|.
265 xkeyevent.xkey.keycode = XKeysymToKeycode(
266 gfx::GetXDisplay(),
267 ui::XKeysymForWindowsKeyCode(key_code, flags & ui::EF_SHIFT_DOWN));
268 UpdateX11EventMask(flags, &xkeyevent.xkey.state);
269 ui::KeyEvent x11_key_event(&xkeyevent, false);
270 rewritten_key_event = new ui::KeyEvent(x11_key_event);
271 }
272 #endif
273 if (!rewritten_key_event)
274 rewritten_key_event = new ui::KeyEvent(key_event);
275 rewritten_key_event->set_flags(flags);
276 rewritten_key_event->set_key_code(key_code);
277 rewritten_key_event->set_character(
278 ui::GetCharacterFromKeyCode(key_code, flags));
279 rewritten_key_event->NormalizeFlags();
280 rewritten_event->reset(rewritten_key_event);
281 }
282
249 void EventRewriter::DeviceKeyPressedOrReleased(int device_id) { 283 void EventRewriter::DeviceKeyPressedOrReleased(int device_id) {
250 if (!device_id_to_type_.count(device_id)) { 284 if (!device_id_to_type_.count(device_id))
251 // |device_id| is unknown. This means the device was connected before 285 KeyboardDeviceAdded(device_id);
252 // booting the OS. Query the name of the device and add it to the map. 286 last_keyboard_device_id_ = device_id;
253 DeviceAdded(device_id);
254 }
255 last_device_id_ = device_id;
256 } 287 }
257 #endif
258 288
259 const PrefService* EventRewriter::GetPrefService() const { 289 const PrefService* EventRewriter::GetPrefService() const {
260 if (pref_service_for_testing_) 290 if (pref_service_for_testing_)
261 return pref_service_for_testing_; 291 return pref_service_for_testing_;
262 Profile* profile = ProfileManager::GetActiveUserProfile(); 292 Profile* profile = ProfileManager::GetActiveUserProfile();
263 return profile ? profile->GetPrefs() : NULL; 293 return profile ? profile->GetPrefs() : NULL;
264 } 294 }
265 295
266 bool EventRewriter::IsAppleKeyboard() const { 296 bool EventRewriter::IsAppleKeyboard() const {
267 if (last_device_id_ == kBadDeviceId) 297 if (last_keyboard_device_id_ == ui::ED_UNKNOWN_DEVICE)
268 return false; 298 return false;
269 299
270 // Check which device generated |event|. 300 // Check which device generated |event|.
271 std::map<int, DeviceType>::const_iterator iter = 301 std::map<int, DeviceType>::const_iterator iter =
272 device_id_to_type_.find(last_device_id_); 302 device_id_to_type_.find(last_keyboard_device_id_);
273 if (iter == device_id_to_type_.end()) { 303 if (iter == device_id_to_type_.end()) {
274 LOG(ERROR) << "Device ID " << last_device_id_ << " is unknown."; 304 LOG(ERROR) << "Device ID " << last_keyboard_device_id_ << " is unknown.";
275 return false; 305 return false;
276 } 306 }
277 307
278 const DeviceType type = iter->second; 308 const DeviceType type = iter->second;
279 return type == kDeviceAppleKeyboard; 309 return type == kDeviceAppleKeyboard;
280 } 310 }
281 311
282 bool EventRewriter::TopRowKeysAreFunctionKeys(const ui::KeyEvent& event) const { 312 bool EventRewriter::TopRowKeysAreFunctionKeys(const ui::KeyEvent& event) const {
283 const PrefService* prefs = GetPrefService(); 313 const PrefService* prefs = GetPrefService();
284 if (prefs && prefs->FindPreference(prefs::kLanguageSendFunctionKeys) && 314 if (prefs && prefs->FindPreference(prefs::kLanguageSendFunctionKeys) &&
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 remapped_state->key_code = map.output_key_code; 377 remapped_state->key_code = map.output_key_code;
348 remapped_state->flags = (input.flags & ~map.input_flags) | map.output_flags; 378 remapped_state->flags = (input.flags & ~map.input_flags) | map.output_flags;
349 return true; 379 return true;
350 } 380 }
351 return false; 381 return false;
352 } 382 }
353 383
354 ui::EventRewriteStatus EventRewriter::RewriteKeyEvent( 384 ui::EventRewriteStatus EventRewriter::RewriteKeyEvent(
355 const ui::KeyEvent& key_event, 385 const ui::KeyEvent& key_event,
356 scoped_ptr<ui::Event>* rewritten_event) { 386 scoped_ptr<ui::Event>* rewritten_event) {
387 int device_id = key_event.source_device_id();
Daniel Erat 2014/06/25 17:13:24 nit: i don't think gets used later in the method,
kpschoedel 2014/06/25 19:59:48 Done.
388 if (device_id != ui::ED_UNKNOWN_DEVICE)
389 DeviceKeyPressedOrReleased(device_id);
357 MutableKeyState state = {key_event.flags(), key_event.key_code()}; 390 MutableKeyState state = {key_event.flags(), key_event.key_code()};
358 bool is_send_event = IsSendEvent(key_event); 391 bool is_send_event = IsSendEvent(key_event);
359 if (!is_send_event) { 392 if (!is_send_event) {
360 RewriteModifierKeys(key_event, &state); 393 RewriteModifierKeys(key_event, &state);
361 RewriteNumPadKeys(key_event, &state); 394 RewriteNumPadKeys(key_event, &state);
362 } 395 }
363 ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE; 396 ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE;
364 if (sticky_keys_controller_) { 397 if (sticky_keys_controller_) {
365 status = sticky_keys_controller_->RewriteKeyEvent( 398 status = sticky_keys_controller_->RewriteKeyEvent(
366 key_event, state.key_code, &state.flags); 399 key_event, state.key_code, &state.flags);
367 if (status == ui::EVENT_REWRITE_DISCARD) 400 if (status == ui::EVENT_REWRITE_DISCARD)
368 return ui::EVENT_REWRITE_DISCARD; 401 return ui::EVENT_REWRITE_DISCARD;
369 } 402 }
370 if (!is_send_event) { 403 if (!is_send_event) {
371 RewriteExtendedKeys(key_event, &state); 404 RewriteExtendedKeys(key_event, &state);
372 RewriteFunctionKeys(key_event, &state); 405 RewriteFunctionKeys(key_event, &state);
373 } 406 }
374 if ((key_event.flags() == state.flags) && 407 if ((key_event.flags() == state.flags) &&
375 (key_event.key_code() == state.key_code) && 408 (key_event.key_code() == state.key_code) &&
409 #if defined(USE_X11)
410 // TODO(kpschoedel): This test is present because several consumers of
411 // key events depend on having a native core X11 event, so we rewrite
412 // all XI2 key events (GenericEvent) into corresponding core X11 key
413 // events. Remove this when event consumers no longer care about
414 // native X11 event details (crbug.com/380349).
415 (!key_event.HasNativeEvent() ||
416 (key_event.native_event()->type != GenericEvent)) &&
417 #endif
376 (status == ui::EVENT_REWRITE_CONTINUE)) { 418 (status == ui::EVENT_REWRITE_CONTINUE)) {
377 return ui::EVENT_REWRITE_CONTINUE; 419 return ui::EVENT_REWRITE_CONTINUE;
378 } 420 }
379 // Sticky keys may have returned a result other than |EVENT_REWRITE_CONTINUE|, 421 // 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 422 // 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 423 // might be here because key_event changed, in which case we need to return
382 // |EVENT_REWRITE_REWRITTEN|. 424 // |EVENT_REWRITE_REWRITTEN|.
383 if (status == ui::EVENT_REWRITE_CONTINUE) 425 if (status == ui::EVENT_REWRITE_CONTINUE)
384 status = ui::EVENT_REWRITE_REWRITTEN; 426 status = ui::EVENT_REWRITE_REWRITTEN;
385 ui::KeyEvent* rewritten_key_event = new ui::KeyEvent(key_event); 427 RewrittenKeyEvent(key_event, state.key_code, state.flags, rewritten_event);
386 rewritten_event->reset(rewritten_key_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; 428 return status;
405 } 429 }
406 430
407 ui::EventRewriteStatus EventRewriter::RewriteMouseButtonEvent( 431 ui::EventRewriteStatus EventRewriter::RewriteMouseButtonEvent(
408 const ui::MouseEvent& mouse_event, 432 const ui::MouseEvent& mouse_event,
409 scoped_ptr<ui::Event>* rewritten_event) { 433 scoped_ptr<ui::Event>* rewritten_event) {
410 int flags = mouse_event.flags(); 434 int flags = mouse_event.flags();
411 RewriteLocatedEvent(mouse_event, &flags); 435 RewriteLocatedEvent(mouse_event, &flags);
412 ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE; 436 ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE;
413 if (sticky_keys_controller_) 437 if (sticky_keys_controller_)
414 status = sticky_keys_controller_->RewriteMouseEvent(mouse_event, &flags); 438 status = sticky_keys_controller_->RewriteMouseEvent(mouse_event, &flags);
439 int changed_button = ui::EF_NONE;
440 if ((mouse_event.type() == ui::ET_MOUSE_PRESSED) ||
441 (mouse_event.type() == ui::ET_MOUSE_RELEASED)) {
442 changed_button = RewriteModifierClick(mouse_event, &flags);
443 }
415 if ((mouse_event.flags() == flags) && 444 if ((mouse_event.flags() == flags) &&
416 (status == ui::EVENT_REWRITE_CONTINUE)) { 445 (status == ui::EVENT_REWRITE_CONTINUE)) {
417 return ui::EVENT_REWRITE_CONTINUE; 446 return ui::EVENT_REWRITE_CONTINUE;
418 } 447 }
419 if (status == ui::EVENT_REWRITE_CONTINUE) 448 if (status == ui::EVENT_REWRITE_CONTINUE)
420 status = ui::EVENT_REWRITE_REWRITTEN; 449 status = ui::EVENT_REWRITE_REWRITTEN;
421 ui::MouseEvent* rewritten_mouse_event = new ui::MouseEvent(mouse_event); 450 ui::MouseEvent* rewritten_mouse_event = new ui::MouseEvent(mouse_event);
422 rewritten_event->reset(rewritten_mouse_event); 451 rewritten_event->reset(rewritten_mouse_event);
423 rewritten_mouse_event->set_flags(flags); 452 rewritten_mouse_event->set_flags(flags);
453 if (changed_button != ui::EF_NONE)
454 rewritten_mouse_event->set_changed_button_flags(changed_button);
424 #if defined(USE_X11) 455 #if defined(USE_X11)
425 XEvent* xev = rewritten_mouse_event->native_event(); 456 XEvent* xev = rewritten_mouse_event->native_event();
426 if (xev) { 457 if (xev) {
427 switch (xev->type) { 458 switch (xev->type) {
428 case ButtonPress: 459 case ButtonPress:
429 case ButtonRelease: { 460 case ButtonRelease: {
430 XButtonEvent* xbutton = &(xev->xbutton); 461 XButtonEvent* xbutton = &(xev->xbutton);
431 UpdateX11EventMask(rewritten_mouse_event->flags(), &xbutton->state); 462 UpdateX11EventMask(rewritten_mouse_event->flags(), &xbutton->state);
463 if (changed_button)
464 UpdateX11Button(changed_button, &xbutton->button);
432 break; 465 break;
433 } 466 }
434 case GenericEvent: { 467 case GenericEvent: {
435 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); 468 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data);
436 CHECK(xievent->evtype == XI_ButtonPress || 469 CHECK(xievent->evtype == XI_ButtonPress ||
437 xievent->evtype == XI_ButtonRelease); 470 xievent->evtype == XI_ButtonRelease);
438 UpdateX11EventMask( 471 UpdateX11EventMask(
439 rewritten_mouse_event->flags(), 472 rewritten_mouse_event->flags(),
440 reinterpret_cast<unsigned int*>(&xievent->mods.effective)); 473 reinterpret_cast<unsigned int*>(&xievent->mods.effective));
474 if (changed_button) {
475 UpdateX11Button(changed_button,
476 reinterpret_cast<unsigned int*>(&xievent->detail));
477 }
441 break; 478 break;
442 } 479 }
443 default: 480 default:
444 NOTREACHED(); 481 NOTREACHED();
445 } 482 }
446 } 483 }
447 #endif 484 #endif
448 return status; 485 return status;
449 } 486 }
450 487
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
830 kNumberKeysToFkeys, arraysize(kNumberKeysToFkeys), incoming, state); 867 kNumberKeysToFkeys, arraysize(kNumberKeysToFkeys), incoming, state);
831 } 868 }
832 } 869 }
833 870
834 void EventRewriter::RewriteLocatedEvent(const ui::Event& event, 871 void EventRewriter::RewriteLocatedEvent(const ui::Event& event,
835 int* flags) { 872 int* flags) {
836 const PrefService* pref_service = GetPrefService(); 873 const PrefService* pref_service = GetPrefService();
837 if (!pref_service) 874 if (!pref_service)
838 return; 875 return;
839 876
840 // First, remap modifier masks. 877 // Remap modifier masks.
Daniel Erat 2014/06/25 17:13:24 nit: don't need this comment now
kpschoedel 2014/06/25 19:59:48 Done.
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 // Then, remap Alt+Button1 to Button3.
Daniel Erat 2014/06/25 17:13:24 nit: remove the "Then, " here; it doesn't make muc
kpschoedel 2014/06/25 19:59:48 Done.
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