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 |