Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/wm/window_state.h" | 9 #include "ash/wm/window_state.h" |
| 10 #include "ash/wm/window_util.h" | 10 #include "ash/wm/window_util.h" |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 176 } | 176 } |
| 177 | 177 |
| 178 EventRewriter::DeviceType EventRewriter::DeviceAddedForTesting( | 178 EventRewriter::DeviceType EventRewriter::DeviceAddedForTesting( |
| 179 int device_id, | 179 int device_id, |
| 180 const std::string& device_name) { | 180 const std::string& device_name) { |
| 181 return DeviceAddedInternal(device_id, device_name); | 181 return DeviceAddedInternal(device_id, device_name); |
| 182 } | 182 } |
| 183 | 183 |
| 184 void EventRewriter::RewriteLocatedEventForTesting(const ui::Event& event, | 184 void EventRewriter::RewriteLocatedEventForTesting(const ui::Event& event, |
| 185 int* flags) { | 185 int* flags) { |
| 186 MutableKeyState state = {*flags, ui::VKEY_UNKNOWN}; | 186 RewriteLocatedEvent(event, flags); |
| 187 RewriteLocatedEvent(event, &state); | |
| 188 *flags = state.flags; | |
| 189 } | 187 } |
| 190 | 188 |
| 191 ui::EventRewriteStatus EventRewriter::RewriteEvent( | 189 ui::EventRewriteStatus EventRewriter::RewriteEvent( |
| 192 const ui::Event& event, | 190 const ui::Event& event, |
| 193 scoped_ptr<ui::Event>* rewritten_event) { | 191 scoped_ptr<ui::Event>* rewritten_event) { |
| 194 #if defined(USE_X11) | 192 #if defined(USE_X11) |
| 195 // Do not rewrite an event sent by ui_controls::SendKeyPress(). See | 193 // Do not rewrite an event sent by ui_controls::SendKeyPress(). See |
| 196 // crbug.com/136465. | 194 // crbug.com/136465. |
| 197 XEvent* xev = event.native_event(); | 195 XEvent* xev = event.native_event(); |
| 198 if (xev && xev->xany.send_event) | 196 if (xev && xev->xany.send_event) |
| 199 return ui::EVENT_REWRITE_CONTINUE; | 197 return ui::EVENT_REWRITE_CONTINUE; |
| 200 #endif | 198 #endif |
| 201 switch (event.type()) { | 199 switch (event.type()) { |
| 202 case ui::ET_KEY_PRESSED: | 200 case ui::ET_KEY_PRESSED: |
| 203 case ui::ET_KEY_RELEASED: { | 201 case ui::ET_KEY_RELEASED: |
| 204 const ui::KeyEvent& key_event = static_cast<const ui::KeyEvent&>(event); | 202 return RewriteKeyEvent(static_cast<const ui::KeyEvent&>(event), |
| 205 MutableKeyState state = {key_event.flags(), key_event.key_code()}; | 203 rewritten_event); |
| 206 RewriteModifierKeys(key_event, &state); | |
| 207 RewriteNumPadKeys(key_event, &state); | |
| 208 RewriteExtendedKeys(key_event, &state); | |
| 209 RewriteFunctionKeys(key_event, &state); | |
| 210 if ((key_event.flags() != state.flags) || | |
| 211 (key_event.key_code() != state.key_code)) { | |
| 212 ui::KeyEvent* rewritten_key_event = new ui::KeyEvent(key_event); | |
| 213 rewritten_event->reset(rewritten_key_event); | |
| 214 rewritten_key_event->set_flags(state.flags); | |
| 215 rewritten_key_event->set_key_code(state.key_code); | |
| 216 rewritten_key_event->set_character( | |
| 217 ui::GetCharacterFromKeyCode(state.key_code, state.flags)); | |
| 218 rewritten_key_event->NormalizeFlags(); | |
| 219 #if defined(USE_X11) | |
| 220 xev = rewritten_key_event->native_event(); | |
| 221 if (xev) { | |
| 222 XKeyEvent* xkey = &(xev->xkey); | |
| 223 UpdateX11EventMask(state.flags, &xkey->state); | |
| 224 xkey->keycode = XKeysymToKeycode( | |
| 225 gfx::GetXDisplay(), | |
| 226 ui::XKeysymForWindowsKeyCode(state.key_code, | |
| 227 state.flags & ui::EF_SHIFT_DOWN)); | |
| 228 } | |
| 229 #endif | |
| 230 return ui::EVENT_REWRITE_REWRITTEN; | |
| 231 } | |
| 232 return ui::EVENT_REWRITE_CONTINUE; | |
| 233 } | |
| 234 case ui::ET_MOUSE_PRESSED: | 204 case ui::ET_MOUSE_PRESSED: |
| 235 case ui::ET_MOUSE_RELEASED: | 205 case ui::ET_MOUSE_RELEASED: |
| 206 return RewriteMouseEvent(static_cast<const ui::MouseEvent&>(event), | |
| 207 rewritten_event); | |
| 236 case ui::ET_TOUCH_PRESSED: | 208 case ui::ET_TOUCH_PRESSED: |
| 237 case ui::ET_TOUCH_RELEASED: { | 209 case ui::ET_TOUCH_RELEASED: |
| 238 MutableKeyState state = {event.flags(), ui::VKEY_UNKNOWN}; | 210 return RewriteTouchEvent(static_cast<const ui::TouchEvent&>(event), |
| 239 RewriteLocatedEvent(event, &state); | 211 rewritten_event); |
| 240 if (event.flags() != state.flags) { | |
| 241 if (event.IsMouseEvent()) { | |
| 242 rewritten_event->reset( | |
| 243 new ui::MouseEvent(static_cast<const ui::MouseEvent&>(event))); | |
| 244 } else { | |
| 245 rewritten_event->reset( | |
| 246 new ui::TouchEvent(static_cast<const ui::TouchEvent&>(event))); | |
| 247 } | |
| 248 rewritten_event->get()->set_flags(state.flags); | |
| 249 return ui::EVENT_REWRITE_REWRITTEN; | |
| 250 } | |
| 251 return ui::EVENT_REWRITE_CONTINUE; | |
| 252 } | |
| 253 default: | 212 default: |
| 254 return ui::EVENT_REWRITE_CONTINUE; | 213 return ui::EVENT_REWRITE_CONTINUE; |
| 255 } | 214 } |
| 256 NOTREACHED(); | 215 NOTREACHED(); |
| 257 } | 216 } |
| 258 | 217 |
| 259 ui::EventRewriteStatus EventRewriter::NextDispatchEvent( | 218 ui::EventRewriteStatus EventRewriter::NextDispatchEvent( |
| 260 const ui::Event& last_event, | 219 const ui::Event& last_event, |
| 261 scoped_ptr<ui::Event>* new_event) { | 220 scoped_ptr<ui::Event>* new_event) { |
| 262 NOTREACHED(); | 221 NOTREACHED(); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 357 continue; | 316 continue; |
| 358 if ((input.flags & map.input_flags) != map.input_flags) | 317 if ((input.flags & map.input_flags) != map.input_flags) |
| 359 continue; | 318 continue; |
| 360 remapped_state->key_code = map.output_key_code; | 319 remapped_state->key_code = map.output_key_code; |
| 361 remapped_state->flags = (input.flags & ~map.input_flags) | map.output_flags; | 320 remapped_state->flags = (input.flags & ~map.input_flags) | map.output_flags; |
| 362 return true; | 321 return true; |
| 363 } | 322 } |
| 364 return false; | 323 return false; |
| 365 } | 324 } |
| 366 | 325 |
| 326 ui::EventRewriteStatus EventRewriter::RewriteKeyEvent( | |
| 327 const ui::KeyEvent& key_event, | |
| 328 scoped_ptr<ui::Event>* rewritten_event) { | |
| 329 ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE; | |
| 330 MutableKeyState state = {key_event.flags(), key_event.key_code()}; | |
| 331 RewriteModifierKeys(key_event, &state); | |
| 332 RewriteNumPadKeys(key_event, &state); | |
| 333 RewriteExtendedKeys(key_event, &state); | |
| 334 RewriteFunctionKeys(key_event, &state); | |
| 335 if ((key_event.flags() != state.flags) || | |
| 336 (key_event.key_code() != state.key_code) || | |
| 337 (status != ui::EVENT_REWRITE_CONTINUE)) { | |
|
sadrul
2014/05/14 03:06:01
status here is always _CONTINUE, right?
kpschoedel
2014/05/14 14:46:53
Yes, I forgot to remove that when I copied this co
| |
| 338 if (status == ui::EVENT_REWRITE_CONTINUE) | |
|
sadrul
2014/05/14 03:06:01
ditto
| |
| 339 status = ui::EVENT_REWRITE_REWRITTEN; | |
| 340 ui::KeyEvent* rewritten_key_event = new ui::KeyEvent(key_event); | |
| 341 rewritten_event->reset(rewritten_key_event); | |
| 342 rewritten_key_event->set_flags(state.flags); | |
| 343 rewritten_key_event->set_key_code(state.key_code); | |
| 344 rewritten_key_event->set_character( | |
| 345 ui::GetCharacterFromKeyCode(state.key_code, state.flags)); | |
| 346 rewritten_key_event->NormalizeFlags(); | |
| 347 #if defined(USE_X11) | |
| 348 XEvent* xev = rewritten_key_event->native_event(); | |
| 349 if (xev) { | |
| 350 XKeyEvent* xkey = &(xev->xkey); | |
| 351 UpdateX11EventMask(rewritten_key_event->flags(), &xkey->state); | |
| 352 xkey->keycode = XKeysymToKeycode( | |
| 353 gfx::GetXDisplay(), | |
| 354 ui::XKeysymForWindowsKeyCode(state.key_code, | |
| 355 state.flags & ui::EF_SHIFT_DOWN)); | |
| 356 } | |
| 357 #endif | |
| 358 } | |
| 359 return status; | |
| 360 } | |
| 361 | |
| 362 ui::EventRewriteStatus EventRewriter::RewriteMouseEvent( | |
| 363 const ui::MouseEvent& mouse_event, | |
| 364 scoped_ptr<ui::Event>* rewritten_event) { | |
| 365 ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE; | |
| 366 int flags = mouse_event.flags(); | |
| 367 RewriteLocatedEvent(mouse_event, &flags); | |
| 368 if (mouse_event.flags() != flags) { | |
| 369 status = ui::EVENT_REWRITE_REWRITTEN; | |
| 370 ui::MouseEvent* rewritten_mouse_event = new ui::MouseEvent(mouse_event); | |
| 371 rewritten_event->reset(rewritten_mouse_event); | |
| 372 rewritten_mouse_event->set_flags(flags); | |
| 373 #if defined(USE_X11) | |
|
kpschoedel
2014/05/12 21:58:03
adopted from ash::StickKeysHandler::AppendModifier
| |
| 374 XEvent* xev = rewritten_mouse_event->native_event(); | |
| 375 if (xev) { | |
| 376 switch (xev->type) { | |
| 377 case ButtonPress: | |
| 378 case ButtonRelease: { | |
| 379 XButtonEvent* xbutton = &(xev->xbutton); | |
| 380 UpdateX11EventMask(rewritten_mouse_event->flags(), &xbutton->state); | |
| 381 break; | |
| 382 } | |
| 383 case GenericEvent: { | |
| 384 XIDeviceEvent* xievent = | |
| 385 static_cast<XIDeviceEvent*>(xev->xcookie.data); | |
| 386 CHECK(xievent->evtype == XI_ButtonPress || | |
| 387 xievent->evtype == XI_ButtonRelease); | |
| 388 UpdateX11EventMask( | |
| 389 rewritten_mouse_event->flags(), | |
| 390 reinterpret_cast<unsigned int*>(&xievent->mods.effective)); | |
| 391 break; | |
| 392 } | |
| 393 default: | |
| 394 NOTREACHED(); | |
| 395 } | |
| 396 } | |
| 397 #endif | |
| 398 } | |
| 399 return status; | |
| 400 } | |
| 401 | |
| 402 ui::EventRewriteStatus EventRewriter::RewriteTouchEvent( | |
| 403 const ui::TouchEvent& touch_event, | |
| 404 scoped_ptr<ui::Event>* rewritten_event) { | |
| 405 ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE; | |
| 406 int flags = touch_event.flags(); | |
| 407 RewriteLocatedEvent(touch_event, &flags); | |
| 408 if (touch_event.flags() != flags) { | |
| 409 status = ui::EVENT_REWRITE_REWRITTEN; | |
| 410 ui::TouchEvent* rewritten_touch_event = new ui::TouchEvent(touch_event); | |
| 411 rewritten_event->reset(rewritten_touch_event); | |
| 412 rewritten_touch_event->set_flags(flags); | |
| 413 #if defined(USE_X11) | |
| 414 XEvent* xev = rewritten_touch_event->native_event(); | |
| 415 if (xev) { | |
| 416 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); | |
| 417 if (xievent) { | |
| 418 UpdateX11EventMask( | |
| 419 rewritten_touch_event->flags(), | |
| 420 reinterpret_cast<unsigned int*>(&xievent->mods.effective)); | |
| 421 } | |
| 422 } | |
| 423 #endif | |
| 424 } | |
| 425 return status; | |
| 426 } | |
| 427 | |
| 367 void EventRewriter::RewriteModifierKeys(const ui::KeyEvent& key_event, | 428 void EventRewriter::RewriteModifierKeys(const ui::KeyEvent& key_event, |
| 368 MutableKeyState* state) { | 429 MutableKeyState* state) { |
| 369 DCHECK(key_event.type() == ui::ET_KEY_PRESSED || | 430 DCHECK(key_event.type() == ui::ET_KEY_PRESSED || |
| 370 key_event.type() == ui::ET_KEY_RELEASED); | 431 key_event.type() == ui::ET_KEY_RELEASED); |
| 371 | 432 |
| 372 // Do nothing if we have just logged in as guest but have not restarted chrome | 433 // Do nothing if we have just logged in as guest but have not restarted chrome |
| 373 // process yet (so we are still on the login screen). In this situations we | 434 // process yet (so we are still on the login screen). In this situations we |
| 374 // have no user profile so can not do anything useful. | 435 // have no user profile so can not do anything useful. |
| 375 // Note that currently, unlike other accounts, when user logs in as guest, we | 436 // Note that currently, unlike other accounts, when user logs in as guest, we |
| 376 // restart chrome process. In future this is to be changed. | 437 // restart chrome process. In future this is to be changed. |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 646 {ui::VKEY_9, ui::EF_COMMAND_DOWN, ui::VKEY_F9, 0}, | 707 {ui::VKEY_9, ui::EF_COMMAND_DOWN, ui::VKEY_F9, 0}, |
| 647 {ui::VKEY_0, ui::EF_COMMAND_DOWN, ui::VKEY_F10, 0}, | 708 {ui::VKEY_0, ui::EF_COMMAND_DOWN, ui::VKEY_F10, 0}, |
| 648 {ui::VKEY_OEM_MINUS, ui::EF_COMMAND_DOWN, ui::VKEY_F11, 0}, | 709 {ui::VKEY_OEM_MINUS, ui::EF_COMMAND_DOWN, ui::VKEY_F11, 0}, |
| 649 {ui::VKEY_OEM_PLUS, ui::EF_COMMAND_DOWN, ui::VKEY_F12, 0}}; | 710 {ui::VKEY_OEM_PLUS, ui::EF_COMMAND_DOWN, ui::VKEY_F12, 0}}; |
| 650 rewritten = RewriteWithKeyboardRemappingsByKeyCode( | 711 rewritten = RewriteWithKeyboardRemappingsByKeyCode( |
| 651 kNumberKeysToFkeys, arraysize(kNumberKeysToFkeys), incoming, state); | 712 kNumberKeysToFkeys, arraysize(kNumberKeysToFkeys), incoming, state); |
| 652 } | 713 } |
| 653 } | 714 } |
| 654 | 715 |
| 655 void EventRewriter::RewriteLocatedEvent(const ui::Event& event, | 716 void EventRewriter::RewriteLocatedEvent(const ui::Event& event, |
| 656 MutableKeyState* state) { | 717 int* flags) { |
| 657 const PrefService* pref_service = GetPrefService(); | 718 const PrefService* pref_service = GetPrefService(); |
| 658 if (!pref_service) | 719 if (!pref_service) |
| 659 return; | 720 return; |
| 660 | 721 |
| 661 // First, remap modifier masks. | 722 // First, remap modifier masks. |
| 662 state->flags = GetRemappedModifierMasks(*pref_service, event, state->flags); | 723 *flags = GetRemappedModifierMasks(*pref_service, event, *flags); |
| 663 | 724 |
| 664 #if defined(USE_X11) | 725 #if defined(USE_X11) |
| 665 // TODO(kpschoedel): de-X11 with unified device ids from crbug.com/360377 | 726 // TODO(kpschoedel): de-X11 with unified device ids from crbug.com/360377 |
| 666 XEvent* xevent = event.native_event(); | 727 XEvent* xevent = event.native_event(); |
| 667 if (!xevent || xevent->type != GenericEvent) | 728 if (!xevent || xevent->type != GenericEvent) |
| 668 return; | 729 return; |
| 669 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xevent->xcookie.data); | 730 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xevent->xcookie.data); |
| 670 if (xievent->evtype != XI_ButtonPress && xievent->evtype != XI_ButtonRelease) | 731 if (xievent->evtype != XI_ButtonPress && xievent->evtype != XI_ButtonRelease) |
| 671 return; | 732 return; |
| 733 UpdateX11EventMask(*flags, | |
|
kpschoedel
2014/05/12 21:58:03
Essential to get the native flags for the remapped
| |
| 734 reinterpret_cast<unsigned int*>(&xievent->mods.effective)); | |
| 672 | 735 |
| 673 // Then, remap Alt+Button1 to Button3. | 736 // Then, remap Alt+Button1 to Button3. |
| 674 if ((xievent->evtype == XI_ButtonPress || | 737 if ((xievent->evtype == XI_ButtonPress || |
| 675 pressed_device_ids_.count(xievent->sourceid)) && | 738 pressed_device_ids_.count(xievent->sourceid)) && |
| 676 (xievent->mods.effective & Mod1Mask) && xievent->detail == Button1) { | 739 (xievent->mods.effective & Mod1Mask) && xievent->detail == Button1) { |
| 677 state->flags &= ~(ui::EF_ALT_DOWN | ui::EF_LEFT_MOUSE_BUTTON); | 740 *flags &= ~(ui::EF_ALT_DOWN | ui::EF_LEFT_MOUSE_BUTTON); |
| 678 state->flags |= ui::EF_RIGHT_MOUSE_BUTTON; | 741 *flags |= ui::EF_RIGHT_MOUSE_BUTTON; |
| 679 xievent->mods.effective &= ~Mod1Mask; | 742 xievent->mods.effective &= ~Mod1Mask; |
| 680 xievent->detail = Button3; | 743 xievent->detail = Button3; |
| 681 if (xievent->evtype == XI_ButtonRelease) { | 744 if (xievent->evtype == XI_ButtonRelease) { |
| 682 // On the release clear the left button from the existing state and the | 745 // On the release clear the left button from the existing state and the |
| 683 // mods, and set the right button. | 746 // mods, and set the right button. |
| 684 XISetMask(xievent->buttons.mask, Button3); | 747 XISetMask(xievent->buttons.mask, Button3); |
| 685 XIClearMask(xievent->buttons.mask, Button1); | 748 XIClearMask(xievent->buttons.mask, Button1); |
| 686 xievent->mods.effective &= ~Button1Mask; | 749 xievent->mods.effective &= ~Button1Mask; |
| 687 pressed_device_ids_.erase(xievent->sourceid); | 750 pressed_device_ids_.erase(xievent->sourceid); |
| 688 } else { | 751 } else { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 752 | 815 |
| 753 XIFreeDeviceInfo(device_info); | 816 XIFreeDeviceInfo(device_info); |
| 754 } | 817 } |
| 755 | 818 |
| 756 void EventRewriter::DeviceRemoved(int device_id) { | 819 void EventRewriter::DeviceRemoved(int device_id) { |
| 757 device_id_to_type_.erase(device_id); | 820 device_id_to_type_.erase(device_id); |
| 758 } | 821 } |
| 759 #endif | 822 #endif |
| 760 | 823 |
| 761 } // namespace chromeos | 824 } // namespace chromeos |
| OLD | NEW |