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 |