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 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 362 continue; | 321 continue; |
| 363 if ((input.flags & map.input_flags) != map.input_flags) | 322 if ((input.flags & map.input_flags) != map.input_flags) |
| 364 continue; | 323 continue; |
| 365 remapped_state->key_code = map.output_key_code; | 324 remapped_state->key_code = map.output_key_code; |
| 366 remapped_state->flags = (input.flags & ~map.input_flags) | map.output_flags; | 325 remapped_state->flags = (input.flags & ~map.input_flags) | map.output_flags; |
| 367 return true; | 326 return true; |
| 368 } | 327 } |
| 369 return false; | 328 return false; |
| 370 } | 329 } |
| 371 | 330 |
| 331 ui::EventRewriteStatus EventRewriter::RewriteKeyEvent( | |
| 332 const ui::KeyEvent& key_event, | |
| 333 scoped_ptr<ui::Event>* rewritten_event) { | |
| 334 MutableKeyState state = {key_event.flags(), key_event.key_code()}; | |
| 335 RewriteModifierKeys(key_event, &state); | |
| 336 RewriteNumPadKeys(key_event, &state); | |
| 337 RewriteExtendedKeys(key_event, &state); | |
| 338 RewriteFunctionKeys(key_event, &state); | |
| 339 if ((key_event.flags() == state.flags) && | |
| 340 (key_event.key_code() == state.key_code)) { | |
| 341 return ui::EVENT_REWRITE_CONTINUE; | |
| 342 } | |
| 343 ui::KeyEvent* rewritten_key_event = new ui::KeyEvent(key_event); | |
| 344 rewritten_event->reset(rewritten_key_event); | |
| 345 rewritten_key_event->set_flags(state.flags); | |
| 346 rewritten_key_event->set_key_code(state.key_code); | |
| 347 rewritten_key_event->set_character( | |
| 348 ui::GetCharacterFromKeyCode(state.key_code, state.flags)); | |
| 349 rewritten_key_event->NormalizeFlags(); | |
| 350 #if defined(USE_X11) | |
| 351 XEvent* xev = rewritten_key_event->native_event(); | |
| 352 if (xev) { | |
| 353 XKeyEvent* xkey = &(xev->xkey); | |
|
sadrul
2014/06/02 00:19:52
Add a CHECK here that xev->type == KeyPress or Key
kpschoedel
2014/06/02 00:52:36
Done.
| |
| 354 UpdateX11EventMask(rewritten_key_event->flags(), &xkey->state); | |
| 355 xkey->keycode = | |
| 356 XKeysymToKeycode(gfx::GetXDisplay(), | |
| 357 ui::XKeysymForWindowsKeyCode( | |
| 358 state.key_code, state.flags & ui::EF_SHIFT_DOWN)); | |
| 359 } | |
| 360 #endif | |
| 361 return ui::EVENT_REWRITE_REWRITTEN; | |
| 362 } | |
| 363 | |
| 364 ui::EventRewriteStatus EventRewriter::RewriteMouseEvent( | |
| 365 const ui::MouseEvent& mouse_event, | |
| 366 scoped_ptr<ui::Event>* rewritten_event) { | |
| 367 int flags = mouse_event.flags(); | |
| 368 RewriteLocatedEvent(mouse_event, &flags); | |
| 369 if (mouse_event.flags() == flags) | |
| 370 return ui::EVENT_REWRITE_CONTINUE; | |
| 371 ui::MouseEvent* rewritten_mouse_event = new ui::MouseEvent(mouse_event); | |
| 372 rewritten_event->reset(rewritten_mouse_event); | |
| 373 rewritten_mouse_event->set_flags(flags); | |
| 374 #if defined(USE_X11) | |
| 375 XEvent* xev = rewritten_mouse_event->native_event(); | |
| 376 if (xev) { | |
| 377 switch (xev->type) { | |
| 378 case ButtonPress: | |
| 379 case ButtonRelease: { | |
| 380 XButtonEvent* xbutton = &(xev->xbutton); | |
| 381 UpdateX11EventMask(rewritten_mouse_event->flags(), &xbutton->state); | |
| 382 break; | |
| 383 } | |
| 384 case GenericEvent: { | |
| 385 XIDeviceEvent* xievent = 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 return ui::EVENT_REWRITE_REWRITTEN; | |
| 399 } | |
| 400 | |
| 401 ui::EventRewriteStatus EventRewriter::RewriteTouchEvent( | |
| 402 const ui::TouchEvent& touch_event, | |
| 403 scoped_ptr<ui::Event>* rewritten_event) { | |
| 404 int flags = touch_event.flags(); | |
| 405 RewriteLocatedEvent(touch_event, &flags); | |
| 406 if (touch_event.flags() == flags) | |
| 407 return ui::EVENT_REWRITE_CONTINUE; | |
| 408 ui::TouchEvent* rewritten_touch_event = new ui::TouchEvent(touch_event); | |
| 409 rewritten_event->reset(rewritten_touch_event); | |
| 410 rewritten_touch_event->set_flags(flags); | |
| 411 #if defined(USE_X11) | |
| 412 XEvent* xev = rewritten_touch_event->native_event(); | |
| 413 if (xev) { | |
| 414 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); | |
| 415 if (xievent) { | |
| 416 UpdateX11EventMask( | |
| 417 rewritten_touch_event->flags(), | |
| 418 reinterpret_cast<unsigned int*>(&xievent->mods.effective)); | |
| 419 } | |
| 420 } | |
| 421 #endif | |
| 422 return ui::EVENT_REWRITE_REWRITTEN; | |
| 423 } | |
| 424 | |
| 372 void EventRewriter::RewriteModifierKeys(const ui::KeyEvent& key_event, | 425 void EventRewriter::RewriteModifierKeys(const ui::KeyEvent& key_event, |
| 373 MutableKeyState* state) { | 426 MutableKeyState* state) { |
| 374 DCHECK(key_event.type() == ui::ET_KEY_PRESSED || | 427 DCHECK(key_event.type() == ui::ET_KEY_PRESSED || |
| 375 key_event.type() == ui::ET_KEY_RELEASED); | 428 key_event.type() == ui::ET_KEY_RELEASED); |
| 376 | 429 |
| 377 // Do nothing if we have just logged in as guest but have not restarted chrome | 430 // Do nothing if we have just logged in as guest but have not restarted chrome |
| 378 // process yet (so we are still on the login screen). In this situations we | 431 // process yet (so we are still on the login screen). In this situations we |
| 379 // have no user profile so can not do anything useful. | 432 // have no user profile so can not do anything useful. |
| 380 // Note that currently, unlike other accounts, when user logs in as guest, we | 433 // Note that currently, unlike other accounts, when user logs in as guest, we |
| 381 // restart chrome process. In future this is to be changed. | 434 // restart chrome process. In future this is to be changed. |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 651 {ui::VKEY_9, ui::EF_COMMAND_DOWN, ui::VKEY_F9, 0}, | 704 {ui::VKEY_9, ui::EF_COMMAND_DOWN, ui::VKEY_F9, 0}, |
| 652 {ui::VKEY_0, ui::EF_COMMAND_DOWN, ui::VKEY_F10, 0}, | 705 {ui::VKEY_0, ui::EF_COMMAND_DOWN, ui::VKEY_F10, 0}, |
| 653 {ui::VKEY_OEM_MINUS, ui::EF_COMMAND_DOWN, ui::VKEY_F11, 0}, | 706 {ui::VKEY_OEM_MINUS, ui::EF_COMMAND_DOWN, ui::VKEY_F11, 0}, |
| 654 {ui::VKEY_OEM_PLUS, ui::EF_COMMAND_DOWN, ui::VKEY_F12, 0}}; | 707 {ui::VKEY_OEM_PLUS, ui::EF_COMMAND_DOWN, ui::VKEY_F12, 0}}; |
| 655 rewritten = RewriteWithKeyboardRemappingsByKeyCode( | 708 rewritten = RewriteWithKeyboardRemappingsByKeyCode( |
| 656 kNumberKeysToFkeys, arraysize(kNumberKeysToFkeys), incoming, state); | 709 kNumberKeysToFkeys, arraysize(kNumberKeysToFkeys), incoming, state); |
| 657 } | 710 } |
| 658 } | 711 } |
| 659 | 712 |
| 660 void EventRewriter::RewriteLocatedEvent(const ui::Event& event, | 713 void EventRewriter::RewriteLocatedEvent(const ui::Event& event, |
| 661 MutableKeyState* state) { | 714 int* flags) { |
| 662 const PrefService* pref_service = GetPrefService(); | 715 const PrefService* pref_service = GetPrefService(); |
| 663 if (!pref_service) | 716 if (!pref_service) |
| 664 return; | 717 return; |
| 665 | 718 |
| 666 // First, remap modifier masks. | 719 // First, remap modifier masks. |
| 667 state->flags = GetRemappedModifierMasks(*pref_service, event, state->flags); | 720 *flags = GetRemappedModifierMasks(*pref_service, event, *flags); |
| 668 | 721 |
| 669 #if defined(USE_X11) | 722 #if defined(USE_X11) |
| 670 // TODO(kpschoedel): de-X11 with unified device ids from crbug.com/360377 | 723 // TODO(kpschoedel): de-X11 with unified device ids from crbug.com/360377 |
| 671 XEvent* xevent = event.native_event(); | 724 XEvent* xevent = event.native_event(); |
| 672 if (!xevent || xevent->type != GenericEvent) | 725 if (!xevent || xevent->type != GenericEvent) |
| 673 return; | 726 return; |
| 674 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xevent->xcookie.data); | 727 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xevent->xcookie.data); |
| 675 if (xievent->evtype != XI_ButtonPress && xievent->evtype != XI_ButtonRelease) | 728 if (xievent->evtype != XI_ButtonPress && xievent->evtype != XI_ButtonRelease) |
| 676 return; | 729 return; |
| 730 UpdateX11EventMask(*flags, | |
| 731 reinterpret_cast<unsigned int*>(&xievent->mods.effective)); | |
|
sadrul
2014/06/02 00:19:52
Should this happen after |flags| is changed in lin
kpschoedel
2014/06/02 00:52:36
No, this is updating the native (X11) flags so tha
sadrul
2014/06/02 00:58:47
In that case, do we need to UpdateX11EventMask() a
| |
| 677 | 732 |
| 678 // Then, remap Alt+Button1 to Button3. | 733 // Then, remap Alt+Button1 to Button3. |
| 679 if ((xievent->evtype == XI_ButtonPress || | 734 if ((xievent->evtype == XI_ButtonPress || |
| 680 pressed_device_ids_.count(xievent->sourceid)) && | 735 pressed_device_ids_.count(xievent->sourceid)) && |
| 681 (xievent->mods.effective & Mod1Mask) && xievent->detail == Button1) { | 736 (xievent->mods.effective & Mod1Mask) && xievent->detail == Button1) { |
| 682 state->flags &= ~(ui::EF_ALT_DOWN | ui::EF_LEFT_MOUSE_BUTTON); | 737 *flags &= ~(ui::EF_ALT_DOWN | ui::EF_LEFT_MOUSE_BUTTON); |
| 683 state->flags |= ui::EF_RIGHT_MOUSE_BUTTON; | 738 *flags |= ui::EF_RIGHT_MOUSE_BUTTON; |
| 684 xievent->mods.effective &= ~Mod1Mask; | 739 xievent->mods.effective &= ~Mod1Mask; |
| 685 xievent->detail = Button3; | 740 xievent->detail = Button3; |
| 686 if (xievent->evtype == XI_ButtonRelease) { | 741 if (xievent->evtype == XI_ButtonRelease) { |
| 687 // On the release clear the left button from the existing state and the | 742 // On the release clear the left button from the existing state and the |
| 688 // mods, and set the right button. | 743 // mods, and set the right button. |
| 689 XISetMask(xievent->buttons.mask, Button3); | 744 XISetMask(xievent->buttons.mask, Button3); |
| 690 XIClearMask(xievent->buttons.mask, Button1); | 745 XIClearMask(xievent->buttons.mask, Button1); |
| 691 xievent->mods.effective &= ~Button1Mask; | 746 xievent->mods.effective &= ~Button1Mask; |
| 692 pressed_device_ids_.erase(xievent->sourceid); | 747 pressed_device_ids_.erase(xievent->sourceid); |
| 693 } else { | 748 } else { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 757 | 812 |
| 758 XIFreeDeviceInfo(device_info); | 813 XIFreeDeviceInfo(device_info); |
| 759 } | 814 } |
| 760 | 815 |
| 761 void EventRewriter::DeviceRemoved(int device_id) { | 816 void EventRewriter::DeviceRemoved(int device_id) { |
| 762 device_id_to_type_.erase(device_id); | 817 device_id_to_type_.erase(device_id); |
| 763 } | 818 } |
| 764 #endif | 819 #endif |
| 765 | 820 |
| 766 } // namespace chromeos | 821 } // namespace chromeos |
| OLD | NEW |