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 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 130 void UpdateX11EventMask(int ui_flags, unsigned int* x_flags) { | 130 void UpdateX11EventMask(int ui_flags, unsigned int* x_flags) { |
| 131 static struct { | 131 static struct { |
| 132 int ui; | 132 int ui; |
| 133 int x; | 133 int x; |
| 134 } flags[] = { | 134 } flags[] = { |
| 135 {ui::EF_CONTROL_DOWN, ControlMask}, | 135 {ui::EF_CONTROL_DOWN, ControlMask}, |
| 136 {ui::EF_SHIFT_DOWN, ShiftMask}, | 136 {ui::EF_SHIFT_DOWN, ShiftMask}, |
| 137 {ui::EF_ALT_DOWN, Mod1Mask}, | 137 {ui::EF_ALT_DOWN, Mod1Mask}, |
| 138 {ui::EF_CAPS_LOCK_DOWN, LockMask}, | 138 {ui::EF_CAPS_LOCK_DOWN, LockMask}, |
| 139 {ui::EF_ALTGR_DOWN, Mod5Mask}, | 139 {ui::EF_ALTGR_DOWN, Mod5Mask}, |
| 140 {ui::EF_COMMAND_DOWN, Mod4Mask}, | 140 {ui::EF_COMMAND_DOWN, Mod4Mask}, |
|
kpschoedel
2014/06/02 00:52:36
From rebase.
| |
| 141 {ui::EF_MOD3_DOWN, Mod3Mask}, | 141 {ui::EF_MOD3_DOWN, Mod3Mask}, |
| 142 {ui::EF_NUMPAD_KEY, Mod2Mask}, | 142 {ui::EF_NUMPAD_KEY, Mod2Mask}, |
| 143 {ui::EF_LEFT_MOUSE_BUTTON, Button1Mask}, | 143 {ui::EF_LEFT_MOUSE_BUTTON, Button1Mask}, |
| 144 {ui::EF_MIDDLE_MOUSE_BUTTON, Button2Mask}, | 144 {ui::EF_MIDDLE_MOUSE_BUTTON, Button2Mask}, |
| 145 {ui::EF_RIGHT_MOUSE_BUTTON, Button3Mask}, | 145 {ui::EF_RIGHT_MOUSE_BUTTON, Button3Mask}, |
| 146 }; | 146 }; |
| 147 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(flags); ++i) { | 147 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(flags); ++i) { |
| 148 if (ui_flags & flags[i].ui) | 148 if (ui_flags & flags[i].ui) |
| 149 *x_flags |= flags[i].x; | 149 *x_flags |= flags[i].x; |
| 150 else | 150 else |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 177 } | 177 } |
| 178 | 178 |
| 179 EventRewriter::DeviceType EventRewriter::DeviceAddedForTesting( | 179 EventRewriter::DeviceType EventRewriter::DeviceAddedForTesting( |
| 180 int device_id, | 180 int device_id, |
| 181 const std::string& device_name) { | 181 const std::string& device_name) { |
| 182 return DeviceAddedInternal(device_id, device_name); | 182 return DeviceAddedInternal(device_id, device_name); |
| 183 } | 183 } |
| 184 | 184 |
| 185 void EventRewriter::RewriteLocatedEventForTesting(const ui::Event& event, | 185 void EventRewriter::RewriteLocatedEventForTesting(const ui::Event& event, |
| 186 int* flags) { | 186 int* flags) { |
| 187 MutableKeyState state = {*flags, ui::VKEY_UNKNOWN}; | 187 RewriteLocatedEvent(event, flags); |
| 188 RewriteLocatedEvent(event, &state); | |
| 189 *flags = state.flags; | |
| 190 } | 188 } |
| 191 | 189 |
| 192 ui::EventRewriteStatus EventRewriter::RewriteEvent( | 190 ui::EventRewriteStatus EventRewriter::RewriteEvent( |
| 193 const ui::Event& event, | 191 const ui::Event& event, |
| 194 scoped_ptr<ui::Event>* rewritten_event) { | 192 scoped_ptr<ui::Event>* rewritten_event) { |
| 195 #if defined(USE_X11) | 193 #if defined(USE_X11) |
| 196 // Do not rewrite an event sent by ui_controls::SendKeyPress(). See | 194 // Do not rewrite an event sent by ui_controls::SendKeyPress(). See |
| 197 // crbug.com/136465. | 195 // crbug.com/136465. |
| 198 XEvent* xev = event.native_event(); | 196 XEvent* xev = event.native_event(); |
| 199 if (xev && xev->xany.send_event) | 197 if (xev && xev->xany.send_event) |
| 200 return ui::EVENT_REWRITE_CONTINUE; | 198 return ui::EVENT_REWRITE_CONTINUE; |
| 201 #endif | 199 #endif |
| 202 switch (event.type()) { | 200 switch (event.type()) { |
| 203 case ui::ET_KEY_PRESSED: | 201 case ui::ET_KEY_PRESSED: |
| 204 case ui::ET_KEY_RELEASED: { | 202 case ui::ET_KEY_RELEASED: |
| 205 const ui::KeyEvent& key_event = static_cast<const ui::KeyEvent&>(event); | 203 return RewriteKeyEvent(static_cast<const ui::KeyEvent&>(event), |
| 206 MutableKeyState state = {key_event.flags(), key_event.key_code()}; | 204 rewritten_event); |
| 207 RewriteModifierKeys(key_event, &state); | |
| 208 RewriteNumPadKeys(key_event, &state); | |
| 209 RewriteExtendedKeys(key_event, &state); | |
| 210 RewriteFunctionKeys(key_event, &state); | |
| 211 if ((key_event.flags() != state.flags) || | |
| 212 (key_event.key_code() != state.key_code)) { | |
| 213 ui::KeyEvent* rewritten_key_event = new ui::KeyEvent(key_event); | |
| 214 rewritten_event->reset(rewritten_key_event); | |
| 215 rewritten_key_event->set_flags(state.flags); | |
| 216 rewritten_key_event->set_key_code(state.key_code); | |
| 217 rewritten_key_event->set_character( | |
| 218 ui::GetCharacterFromKeyCode(state.key_code, state.flags)); | |
| 219 rewritten_key_event->NormalizeFlags(); | |
| 220 #if defined(USE_X11) | |
| 221 xev = rewritten_key_event->native_event(); | |
| 222 if (xev) { | |
| 223 XKeyEvent* xkey = &(xev->xkey); | |
| 224 UpdateX11EventMask(state.flags, &xkey->state); | |
| 225 xkey->keycode = XKeysymToKeycode( | |
| 226 gfx::GetXDisplay(), | |
| 227 ui::XKeysymForWindowsKeyCode(state.key_code, | |
| 228 state.flags & ui::EF_SHIFT_DOWN)); | |
| 229 } | |
| 230 #endif | |
| 231 return ui::EVENT_REWRITE_REWRITTEN; | |
| 232 } | |
| 233 return ui::EVENT_REWRITE_CONTINUE; | |
| 234 } | |
| 235 case ui::ET_MOUSE_PRESSED: | 205 case ui::ET_MOUSE_PRESSED: |
| 236 case ui::ET_MOUSE_RELEASED: | 206 case ui::ET_MOUSE_RELEASED: |
| 207 return RewriteMouseEvent(static_cast<const ui::MouseEvent&>(event), | |
| 208 rewritten_event); | |
| 237 case ui::ET_TOUCH_PRESSED: | 209 case ui::ET_TOUCH_PRESSED: |
| 238 case ui::ET_TOUCH_RELEASED: { | 210 case ui::ET_TOUCH_RELEASED: |
| 239 MutableKeyState state = {event.flags(), ui::VKEY_UNKNOWN}; | 211 return RewriteTouchEvent(static_cast<const ui::TouchEvent&>(event), |
| 240 RewriteLocatedEvent(event, &state); | 212 rewritten_event); |
| 241 if (event.flags() != state.flags) { | |
| 242 if (event.IsMouseEvent()) { | |
| 243 rewritten_event->reset( | |
| 244 new ui::MouseEvent(static_cast<const ui::MouseEvent&>(event))); | |
| 245 } else { | |
| 246 rewritten_event->reset( | |
| 247 new ui::TouchEvent(static_cast<const ui::TouchEvent&>(event))); | |
| 248 } | |
| 249 rewritten_event->get()->set_flags(state.flags); | |
| 250 return ui::EVENT_REWRITE_REWRITTEN; | |
| 251 } | |
| 252 return ui::EVENT_REWRITE_CONTINUE; | |
| 253 } | |
| 254 default: | 213 default: |
| 255 return ui::EVENT_REWRITE_CONTINUE; | 214 return ui::EVENT_REWRITE_CONTINUE; |
| 256 } | 215 } |
| 257 NOTREACHED(); | 216 NOTREACHED(); |
| 258 } | 217 } |
| 259 | 218 |
| 260 ui::EventRewriteStatus EventRewriter::NextDispatchEvent( | 219 ui::EventRewriteStatus EventRewriter::NextDispatchEvent( |
| 261 const ui::Event& last_event, | 220 const ui::Event& last_event, |
| 262 scoped_ptr<ui::Event>* new_event) { | 221 scoped_ptr<ui::Event>* new_event) { |
| 263 NOTREACHED(); | 222 NOTREACHED(); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 363 continue; | 322 continue; |
| 364 if ((input.flags & map.input_flags) != map.input_flags) | 323 if ((input.flags & map.input_flags) != map.input_flags) |
| 365 continue; | 324 continue; |
| 366 remapped_state->key_code = map.output_key_code; | 325 remapped_state->key_code = map.output_key_code; |
| 367 remapped_state->flags = (input.flags & ~map.input_flags) | map.output_flags; | 326 remapped_state->flags = (input.flags & ~map.input_flags) | map.output_flags; |
| 368 return true; | 327 return true; |
| 369 } | 328 } |
| 370 return false; | 329 return false; |
| 371 } | 330 } |
| 372 | 331 |
| 332 ui::EventRewriteStatus EventRewriter::RewriteKeyEvent( | |
| 333 const ui::KeyEvent& key_event, | |
| 334 scoped_ptr<ui::Event>* rewritten_event) { | |
| 335 MutableKeyState state = {key_event.flags(), key_event.key_code()}; | |
| 336 RewriteModifierKeys(key_event, &state); | |
| 337 RewriteNumPadKeys(key_event, &state); | |
| 338 RewriteExtendedKeys(key_event, &state); | |
| 339 RewriteFunctionKeys(key_event, &state); | |
| 340 if ((key_event.flags() == state.flags) && | |
| 341 (key_event.key_code() == state.key_code)) { | |
| 342 return ui::EVENT_REWRITE_CONTINUE; | |
| 343 } | |
| 344 ui::KeyEvent* rewritten_key_event = new ui::KeyEvent(key_event); | |
| 345 rewritten_event->reset(rewritten_key_event); | |
| 346 rewritten_key_event->set_flags(state.flags); | |
| 347 rewritten_key_event->set_key_code(state.key_code); | |
| 348 rewritten_key_event->set_character( | |
| 349 ui::GetCharacterFromKeyCode(state.key_code, state.flags)); | |
| 350 rewritten_key_event->NormalizeFlags(); | |
| 351 #if defined(USE_X11) | |
| 352 XEvent* xev = rewritten_key_event->native_event(); | |
| 353 if (xev) { | |
| 354 CHECK(xev->type == KeyPress || xev->type == KeyRelease); | |
| 355 XKeyEvent* xkey = &(xev->xkey); | |
| 356 UpdateX11EventMask(rewritten_key_event->flags(), &xkey->state); | |
| 357 xkey->keycode = | |
| 358 XKeysymToKeycode(gfx::GetXDisplay(), | |
| 359 ui::XKeysymForWindowsKeyCode( | |
| 360 state.key_code, state.flags & ui::EF_SHIFT_DOWN)); | |
| 361 } | |
| 362 #endif | |
| 363 return ui::EVENT_REWRITE_REWRITTEN; | |
| 364 } | |
| 365 | |
| 366 ui::EventRewriteStatus EventRewriter::RewriteMouseEvent( | |
| 367 const ui::MouseEvent& mouse_event, | |
| 368 scoped_ptr<ui::Event>* rewritten_event) { | |
| 369 int flags = mouse_event.flags(); | |
| 370 RewriteLocatedEvent(mouse_event, &flags); | |
| 371 if (mouse_event.flags() == flags) | |
| 372 return ui::EVENT_REWRITE_CONTINUE; | |
| 373 ui::MouseEvent* rewritten_mouse_event = new ui::MouseEvent(mouse_event); | |
| 374 rewritten_event->reset(rewritten_mouse_event); | |
| 375 rewritten_mouse_event->set_flags(flags); | |
| 376 #if defined(USE_X11) | |
| 377 XEvent* xev = rewritten_mouse_event->native_event(); | |
| 378 if (xev) { | |
| 379 switch (xev->type) { | |
| 380 case ButtonPress: | |
| 381 case ButtonRelease: { | |
| 382 XButtonEvent* xbutton = &(xev->xbutton); | |
| 383 UpdateX11EventMask(rewritten_mouse_event->flags(), &xbutton->state); | |
| 384 break; | |
| 385 } | |
| 386 case GenericEvent: { | |
| 387 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); | |
| 388 CHECK(xievent->evtype == XI_ButtonPress || | |
| 389 xievent->evtype == XI_ButtonRelease); | |
| 390 UpdateX11EventMask( | |
| 391 rewritten_mouse_event->flags(), | |
| 392 reinterpret_cast<unsigned int*>(&xievent->mods.effective)); | |
| 393 break; | |
| 394 } | |
| 395 default: | |
| 396 NOTREACHED(); | |
| 397 } | |
| 398 } | |
| 399 #endif | |
| 400 return ui::EVENT_REWRITE_REWRITTEN; | |
| 401 } | |
| 402 | |
| 403 ui::EventRewriteStatus EventRewriter::RewriteTouchEvent( | |
| 404 const ui::TouchEvent& touch_event, | |
| 405 scoped_ptr<ui::Event>* rewritten_event) { | |
| 406 int flags = touch_event.flags(); | |
| 407 RewriteLocatedEvent(touch_event, &flags); | |
| 408 if (touch_event.flags() == flags) | |
| 409 return ui::EVENT_REWRITE_CONTINUE; | |
| 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 return ui::EVENT_REWRITE_REWRITTEN; | |
| 425 } | |
| 426 | |
| 373 void EventRewriter::RewriteModifierKeys(const ui::KeyEvent& key_event, | 427 void EventRewriter::RewriteModifierKeys(const ui::KeyEvent& key_event, |
| 374 MutableKeyState* state) { | 428 MutableKeyState* state) { |
| 375 DCHECK(key_event.type() == ui::ET_KEY_PRESSED || | 429 DCHECK(key_event.type() == ui::ET_KEY_PRESSED || |
| 376 key_event.type() == ui::ET_KEY_RELEASED); | 430 key_event.type() == ui::ET_KEY_RELEASED); |
| 377 | 431 |
| 378 // Do nothing if we have just logged in as guest but have not restarted chrome | 432 // Do nothing if we have just logged in as guest but have not restarted chrome |
| 379 // process yet (so we are still on the login screen). In this situations we | 433 // process yet (so we are still on the login screen). In this situations we |
| 380 // have no user profile so can not do anything useful. | 434 // have no user profile so can not do anything useful. |
| 381 // Note that currently, unlike other accounts, when user logs in as guest, we | 435 // Note that currently, unlike other accounts, when user logs in as guest, we |
| 382 // restart chrome process. In future this is to be changed. | 436 // restart chrome process. In future this is to be changed. |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 652 {ui::VKEY_9, ui::EF_COMMAND_DOWN, ui::VKEY_F9, 0}, | 706 {ui::VKEY_9, ui::EF_COMMAND_DOWN, ui::VKEY_F9, 0}, |
| 653 {ui::VKEY_0, ui::EF_COMMAND_DOWN, ui::VKEY_F10, 0}, | 707 {ui::VKEY_0, ui::EF_COMMAND_DOWN, ui::VKEY_F10, 0}, |
| 654 {ui::VKEY_OEM_MINUS, ui::EF_COMMAND_DOWN, ui::VKEY_F11, 0}, | 708 {ui::VKEY_OEM_MINUS, ui::EF_COMMAND_DOWN, ui::VKEY_F11, 0}, |
| 655 {ui::VKEY_OEM_PLUS, ui::EF_COMMAND_DOWN, ui::VKEY_F12, 0}}; | 709 {ui::VKEY_OEM_PLUS, ui::EF_COMMAND_DOWN, ui::VKEY_F12, 0}}; |
| 656 rewritten = RewriteWithKeyboardRemappingsByKeyCode( | 710 rewritten = RewriteWithKeyboardRemappingsByKeyCode( |
| 657 kNumberKeysToFkeys, arraysize(kNumberKeysToFkeys), incoming, state); | 711 kNumberKeysToFkeys, arraysize(kNumberKeysToFkeys), incoming, state); |
| 658 } | 712 } |
| 659 } | 713 } |
| 660 | 714 |
| 661 void EventRewriter::RewriteLocatedEvent(const ui::Event& event, | 715 void EventRewriter::RewriteLocatedEvent(const ui::Event& event, |
| 662 MutableKeyState* state) { | 716 int* flags) { |
| 663 const PrefService* pref_service = GetPrefService(); | 717 const PrefService* pref_service = GetPrefService(); |
| 664 if (!pref_service) | 718 if (!pref_service) |
| 665 return; | 719 return; |
| 666 | 720 |
| 667 // First, remap modifier masks. | 721 // First, remap modifier masks. |
| 668 state->flags = GetRemappedModifierMasks(*pref_service, event, state->flags); | 722 *flags = GetRemappedModifierMasks(*pref_service, event, *flags); |
| 669 | 723 |
| 670 #if defined(USE_X11) | 724 #if defined(USE_X11) |
| 671 // TODO(kpschoedel): de-X11 with unified device ids from crbug.com/360377 | 725 // TODO(kpschoedel): de-X11 with unified device ids from crbug.com/360377 |
| 672 XEvent* xevent = event.native_event(); | 726 XEvent* xevent = event.native_event(); |
| 673 if (!xevent || xevent->type != GenericEvent) | 727 if (!xevent || xevent->type != GenericEvent) |
| 674 return; | 728 return; |
| 675 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xevent->xcookie.data); | 729 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xevent->xcookie.data); |
| 676 if (xievent->evtype != XI_ButtonPress && xievent->evtype != XI_ButtonRelease) | 730 if (xievent->evtype != XI_ButtonPress && xievent->evtype != XI_ButtonRelease) |
| 677 return; | 731 return; |
| 732 UpdateX11EventMask(*flags, | |
| 733 reinterpret_cast<unsigned int*>(&xievent->mods.effective)); | |
| 678 | 734 |
| 679 // Then, remap Alt+Button1 to Button3. | 735 // Then, remap Alt+Button1 to Button3. |
| 680 if ((xievent->evtype == XI_ButtonPress || | 736 if ((xievent->evtype == XI_ButtonPress || |
| 681 pressed_device_ids_.count(xievent->sourceid)) && | 737 pressed_device_ids_.count(xievent->sourceid)) && |
| 682 (xievent->mods.effective & Mod1Mask) && xievent->detail == Button1) { | 738 (xievent->mods.effective & Mod1Mask) && xievent->detail == Button1) { |
| 683 state->flags &= ~(ui::EF_ALT_DOWN | ui::EF_LEFT_MOUSE_BUTTON); | 739 *flags &= ~(ui::EF_ALT_DOWN | ui::EF_LEFT_MOUSE_BUTTON); |
| 684 state->flags |= ui::EF_RIGHT_MOUSE_BUTTON; | 740 *flags |= ui::EF_RIGHT_MOUSE_BUTTON; |
| 685 xievent->mods.effective &= ~Mod1Mask; | 741 xievent->mods.effective &= ~Mod1Mask; |
| 686 xievent->detail = Button3; | 742 xievent->detail = Button3; |
| 687 if (xievent->evtype == XI_ButtonRelease) { | 743 if (xievent->evtype == XI_ButtonRelease) { |
| 688 // On the release clear the left button from the existing state and the | 744 // On the release clear the left button from the existing state and the |
| 689 // mods, and set the right button. | 745 // mods, and set the right button. |
| 690 XISetMask(xievent->buttons.mask, Button3); | 746 XISetMask(xievent->buttons.mask, Button3); |
| 691 XIClearMask(xievent->buttons.mask, Button1); | 747 XIClearMask(xievent->buttons.mask, Button1); |
| 692 xievent->mods.effective &= ~Button1Mask; | 748 xievent->mods.effective &= ~Button1Mask; |
| 693 pressed_device_ids_.erase(xievent->sourceid); | 749 pressed_device_ids_.erase(xievent->sourceid); |
| 694 } else { | 750 } else { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 758 | 814 |
| 759 XIFreeDeviceInfo(device_info); | 815 XIFreeDeviceInfo(device_info); |
| 760 } | 816 } |
| 761 | 817 |
| 762 void EventRewriter::DeviceRemoved(int device_id) { | 818 void EventRewriter::DeviceRemoved(int device_id) { |
| 763 device_id_to_type_.erase(device_id); | 819 device_id_to_type_.erase(device_id); |
| 764 } | 820 } |
| 765 #endif | 821 #endif |
| 766 | 822 |
| 767 } // namespace chromeos | 823 } // namespace chromeos |
| OLD | NEW |