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/sticky_keys/sticky_keys_controller.h" | |
9 #include "ash/wm/window_state.h" | 10 #include "ash/wm/window_state.h" |
10 #include "ash/wm/window_util.h" | 11 #include "ash/wm/window_util.h" |
11 #include "base/command_line.h" | 12 #include "base/command_line.h" |
12 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/macros.h" | |
13 #include "base/prefs/pref_service.h" | 15 #include "base/prefs/pref_service.h" |
14 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
15 #include "base/sys_info.h" | 17 #include "base/sys_info.h" |
16 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h" | 18 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h" |
17 #include "chrome/browser/chromeos/login/users/user_manager.h" | 19 #include "chrome/browser/chromeos/login/users/user_manager.h" |
18 #include "chrome/browser/profiles/profile_manager.h" | 20 #include "chrome/browser/profiles/profile_manager.h" |
19 #include "chrome/common/pref_names.h" | 21 #include "chrome/common/pref_names.h" |
20 #include "chromeos/chromeos_switches.h" | 22 #include "chromeos/chromeos_switches.h" |
21 #include "chromeos/ime/ime_keyboard.h" | 23 #include "chromeos/ime/ime_keyboard.h" |
22 #include "chromeos/ime/input_method_manager.h" | 24 #include "chromeos/ime/input_method_manager.h" |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
148 if (ui_flags & flags[i].ui) | 150 if (ui_flags & flags[i].ui) |
149 *x_flags |= flags[i].x; | 151 *x_flags |= flags[i].x; |
150 else | 152 else |
151 *x_flags &= ~flags[i].x; | 153 *x_flags &= ~flags[i].x; |
152 } | 154 } |
153 } | 155 } |
154 #endif | 156 #endif |
155 | 157 |
156 } // namespace | 158 } // namespace |
157 | 159 |
158 EventRewriter::EventRewriter() | 160 EventRewriter::EventRewriter(ash::StickyKeysController* sticky_keys_controller) |
159 : last_device_id_(kBadDeviceId), | 161 : last_device_id_(kBadDeviceId), |
160 ime_keyboard_for_testing_(NULL), | 162 ime_keyboard_for_testing_(NULL), |
161 pref_service_for_testing_(NULL) { | 163 pref_service_for_testing_(NULL), |
164 sticky_keys_controller_(sticky_keys_controller) { | |
162 #if defined(USE_X11) | 165 #if defined(USE_X11) |
163 ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this); | 166 ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this); |
164 if (base::SysInfo::IsRunningOnChromeOS()) { | 167 if (base::SysInfo::IsRunningOnChromeOS()) { |
165 XInputHierarchyChangedEventListener::GetInstance()->AddObserver(this); | 168 XInputHierarchyChangedEventListener::GetInstance()->AddObserver(this); |
166 } | 169 } |
167 #endif | 170 #endif |
168 } | 171 } |
169 | 172 |
170 EventRewriter::~EventRewriter() { | 173 EventRewriter::~EventRewriter() { |
171 #if defined(USE_X11) | 174 #if defined(USE_X11) |
(...skipping 18 matching lines...) Expand all Loading... | |
190 ui::EventRewriteStatus EventRewriter::RewriteEvent( | 193 ui::EventRewriteStatus EventRewriter::RewriteEvent( |
191 const ui::Event& event, | 194 const ui::Event& event, |
192 scoped_ptr<ui::Event>* rewritten_event) { | 195 scoped_ptr<ui::Event>* rewritten_event) { |
193 #if defined(USE_X11) | 196 #if defined(USE_X11) |
194 // Do not rewrite an event sent by ui_controls::SendKeyPress(). See | 197 // Do not rewrite an event sent by ui_controls::SendKeyPress(). See |
195 // crbug.com/136465. | 198 // crbug.com/136465. |
196 XEvent* xev = event.native_event(); | 199 XEvent* xev = event.native_event(); |
197 if (xev && xev->xany.send_event) | 200 if (xev && xev->xany.send_event) |
198 return ui::EVENT_REWRITE_CONTINUE; | 201 return ui::EVENT_REWRITE_CONTINUE; |
199 #endif | 202 #endif |
200 switch (event.type()) { | 203 if ((event.type() == ui::ET_KEY_PRESSED) || |
201 case ui::ET_KEY_PRESSED: | 204 (event.type() == ui::ET_KEY_RELEASED)) { |
202 case ui::ET_KEY_RELEASED: | 205 return RewriteKeyEvent(static_cast<const ui::KeyEvent&>(event), |
203 return RewriteKeyEvent(static_cast<const ui::KeyEvent&>(event), | 206 rewritten_event); |
207 } | |
208 if (event.IsMouseEvent()) { | |
209 return RewriteMouseEvent(static_cast<const ui::MouseEvent&>(event), | |
204 rewritten_event); | 210 rewritten_event); |
205 case ui::ET_MOUSE_PRESSED: | |
206 case ui::ET_MOUSE_RELEASED: | |
207 return RewriteMouseEvent(static_cast<const ui::MouseEvent&>(event), | |
208 rewritten_event); | |
209 case ui::ET_TOUCH_PRESSED: | |
210 case ui::ET_TOUCH_RELEASED: | |
211 return RewriteTouchEvent(static_cast<const ui::TouchEvent&>(event), | |
212 rewritten_event); | |
213 default: | |
214 return ui::EVENT_REWRITE_CONTINUE; | |
215 } | 211 } |
216 NOTREACHED(); | 212 if ((event.type() == ui::ET_TOUCH_PRESSED) || |
213 (event.type() == ui::ET_TOUCH_RELEASED)) { | |
214 return RewriteTouchEvent(static_cast<const ui::TouchEvent&>(event), | |
215 rewritten_event); | |
216 } | |
217 if (event.IsScrollEvent()) { | |
218 return RewriteScrollEvent(static_cast<const ui::ScrollEvent&>(event), | |
219 rewritten_event); | |
220 } | |
221 return ui::EVENT_REWRITE_CONTINUE; | |
217 } | 222 } |
218 | 223 |
219 ui::EventRewriteStatus EventRewriter::NextDispatchEvent( | 224 ui::EventRewriteStatus EventRewriter::NextDispatchEvent( |
220 const ui::Event& last_event, | 225 const ui::Event& last_event, |
221 scoped_ptr<ui::Event>* new_event) { | 226 scoped_ptr<ui::Event>* new_event) { |
227 if (sticky_keys_controller_) { | |
228 // In the case of sticky keys, we know what the events obtained here are: | |
229 // modifier key releases that match the ones previously discarded. So, we | |
230 // know that they don't have to be passed through the post-sticky key | |
231 // rewriting phases, |RewriteExtendedKeys()| and |RewriteFunctionKeys()|, | |
232 // because those phases do nothing with modifier key releases. | |
233 return sticky_keys_controller_->NextDispatchEvent(new_event); | |
234 } | |
222 NOTREACHED(); | 235 NOTREACHED(); |
223 return ui::EVENT_REWRITE_CONTINUE; | 236 return ui::EVENT_REWRITE_CONTINUE; |
224 } | 237 } |
225 | 238 |
226 #if defined(USE_X11) | 239 #if defined(USE_X11) |
227 void EventRewriter::DeviceKeyPressedOrReleased(int device_id) { | 240 void EventRewriter::DeviceKeyPressedOrReleased(int device_id) { |
228 if (!device_id_to_type_.count(device_id)) { | 241 if (!device_id_to_type_.count(device_id)) { |
229 // |device_id| is unknown. This means the device was connected before | 242 // |device_id| is unknown. This means the device was connected before |
230 // booting the OS. Query the name of the device and add it to the map. | 243 // booting the OS. Query the name of the device and add it to the map. |
231 DeviceAdded(device_id); | 244 DeviceAdded(device_id); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
328 } | 341 } |
329 return false; | 342 return false; |
330 } | 343 } |
331 | 344 |
332 ui::EventRewriteStatus EventRewriter::RewriteKeyEvent( | 345 ui::EventRewriteStatus EventRewriter::RewriteKeyEvent( |
333 const ui::KeyEvent& key_event, | 346 const ui::KeyEvent& key_event, |
334 scoped_ptr<ui::Event>* rewritten_event) { | 347 scoped_ptr<ui::Event>* rewritten_event) { |
335 MutableKeyState state = {key_event.flags(), key_event.key_code()}; | 348 MutableKeyState state = {key_event.flags(), key_event.key_code()}; |
336 RewriteModifierKeys(key_event, &state); | 349 RewriteModifierKeys(key_event, &state); |
337 RewriteNumPadKeys(key_event, &state); | 350 RewriteNumPadKeys(key_event, &state); |
351 ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE; | |
352 if (sticky_keys_controller_) { | |
353 status = sticky_keys_controller_->RewriteKeyEvent( | |
354 key_event, state.key_code, &state.flags); | |
355 if (status == ui::EVENT_REWRITE_DISCARD) | |
356 return ui::EVENT_REWRITE_DISCARD; | |
357 } | |
338 RewriteExtendedKeys(key_event, &state); | 358 RewriteExtendedKeys(key_event, &state); |
339 RewriteFunctionKeys(key_event, &state); | 359 RewriteFunctionKeys(key_event, &state); |
340 if ((key_event.flags() == state.flags) && | 360 if ((key_event.flags() == state.flags) && |
341 (key_event.key_code() == state.key_code)) { | 361 (key_event.key_code() == state.key_code) && |
362 (status == ui::EVENT_REWRITE_CONTINUE)) { | |
342 return ui::EVENT_REWRITE_CONTINUE; | 363 return ui::EVENT_REWRITE_CONTINUE; |
343 } | 364 } |
365 if (status == ui::EVENT_REWRITE_CONTINUE) | |
366 status = ui::EVENT_REWRITE_REWRITTEN; | |
sadrul
2014/06/16 15:07:43
Add a comment here why.
kpschoedel
2014/06/16 15:29:28
Done.
| |
344 ui::KeyEvent* rewritten_key_event = new ui::KeyEvent(key_event); | 367 ui::KeyEvent* rewritten_key_event = new ui::KeyEvent(key_event); |
345 rewritten_event->reset(rewritten_key_event); | 368 rewritten_event->reset(rewritten_key_event); |
346 rewritten_key_event->set_flags(state.flags); | 369 rewritten_key_event->set_flags(state.flags); |
347 rewritten_key_event->set_key_code(state.key_code); | 370 rewritten_key_event->set_key_code(state.key_code); |
348 rewritten_key_event->set_character( | 371 rewritten_key_event->set_character( |
349 ui::GetCharacterFromKeyCode(state.key_code, state.flags)); | 372 ui::GetCharacterFromKeyCode(state.key_code, state.flags)); |
350 rewritten_key_event->NormalizeFlags(); | 373 rewritten_key_event->NormalizeFlags(); |
351 #if defined(USE_X11) | 374 #if defined(USE_X11) |
352 XEvent* xev = rewritten_key_event->native_event(); | 375 XEvent* xev = rewritten_key_event->native_event(); |
353 if (xev) { | 376 if (xev) { |
354 CHECK(xev->type == KeyPress || xev->type == KeyRelease); | 377 CHECK(xev->type == KeyPress || xev->type == KeyRelease); |
355 XKeyEvent* xkey = &(xev->xkey); | 378 XKeyEvent* xkey = &(xev->xkey); |
356 UpdateX11EventMask(rewritten_key_event->flags(), &xkey->state); | 379 UpdateX11EventMask(rewritten_key_event->flags(), &xkey->state); |
357 xkey->keycode = | 380 xkey->keycode = |
358 XKeysymToKeycode(gfx::GetXDisplay(), | 381 XKeysymToKeycode(gfx::GetXDisplay(), |
359 ui::XKeysymForWindowsKeyCode( | 382 ui::XKeysymForWindowsKeyCode( |
360 state.key_code, state.flags & ui::EF_SHIFT_DOWN)); | 383 state.key_code, state.flags & ui::EF_SHIFT_DOWN)); |
361 } | 384 } |
362 #endif | 385 #endif |
363 return ui::EVENT_REWRITE_REWRITTEN; | 386 return status; |
364 } | 387 } |
365 | 388 |
366 ui::EventRewriteStatus EventRewriter::RewriteMouseEvent( | 389 ui::EventRewriteStatus EventRewriter::RewriteMouseEvent( |
367 const ui::MouseEvent& mouse_event, | 390 const ui::MouseEvent& mouse_event, |
368 scoped_ptr<ui::Event>* rewritten_event) { | 391 scoped_ptr<ui::Event>* rewritten_event) { |
369 int flags = mouse_event.flags(); | 392 int flags = mouse_event.flags(); |
370 RewriteLocatedEvent(mouse_event, &flags); | 393 if ((mouse_event.type() == ui::ET_MOUSE_PRESSED) || |
371 if (mouse_event.flags() == flags) | 394 (mouse_event.type() == ui::ET_MOUSE_RELEASED)) { |
395 RewriteLocatedEvent(mouse_event, &flags); | |
396 } | |
397 ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE; | |
398 if (sticky_keys_controller_) | |
399 status = sticky_keys_controller_->RewriteMouseEvent(mouse_event, &flags); | |
400 if ((mouse_event.flags() == flags) && | |
401 (status == ui::EVENT_REWRITE_CONTINUE)) { | |
372 return ui::EVENT_REWRITE_CONTINUE; | 402 return ui::EVENT_REWRITE_CONTINUE; |
403 } | |
404 if (status == ui::EVENT_REWRITE_CONTINUE) | |
405 status = ui::EVENT_REWRITE_REWRITTEN; | |
373 ui::MouseEvent* rewritten_mouse_event = new ui::MouseEvent(mouse_event); | 406 ui::MouseEvent* rewritten_mouse_event = new ui::MouseEvent(mouse_event); |
374 rewritten_event->reset(rewritten_mouse_event); | 407 rewritten_event->reset(rewritten_mouse_event); |
375 rewritten_mouse_event->set_flags(flags); | 408 rewritten_mouse_event->set_flags(flags); |
376 #if defined(USE_X11) | 409 #if defined(USE_X11) |
377 XEvent* xev = rewritten_mouse_event->native_event(); | 410 XEvent* xev = rewritten_mouse_event->native_event(); |
378 if (xev) { | 411 if (xev) { |
379 switch (xev->type) { | 412 switch (xev->type) { |
380 case ButtonPress: | 413 case ButtonPress: |
381 case ButtonRelease: { | 414 case ButtonRelease: { |
382 XButtonEvent* xbutton = &(xev->xbutton); | 415 XButtonEvent* xbutton = &(xev->xbutton); |
383 UpdateX11EventMask(rewritten_mouse_event->flags(), &xbutton->state); | 416 UpdateX11EventMask(rewritten_mouse_event->flags(), &xbutton->state); |
384 break; | 417 break; |
385 } | 418 } |
386 case GenericEvent: { | 419 case GenericEvent: { |
387 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); | 420 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); |
388 CHECK(xievent->evtype == XI_ButtonPress || | 421 CHECK(xievent->evtype == XI_ButtonPress || |
389 xievent->evtype == XI_ButtonRelease); | 422 xievent->evtype == XI_ButtonRelease); |
390 UpdateX11EventMask( | 423 UpdateX11EventMask( |
391 rewritten_mouse_event->flags(), | 424 rewritten_mouse_event->flags(), |
392 reinterpret_cast<unsigned int*>(&xievent->mods.effective)); | 425 reinterpret_cast<unsigned int*>(&xievent->mods.effective)); |
393 break; | 426 break; |
394 } | 427 } |
395 default: | 428 default: |
396 NOTREACHED(); | 429 NOTREACHED(); |
397 } | 430 } |
398 } | 431 } |
399 #endif | 432 #endif |
400 return ui::EVENT_REWRITE_REWRITTEN; | 433 return status; |
401 } | 434 } |
402 | 435 |
403 ui::EventRewriteStatus EventRewriter::RewriteTouchEvent( | 436 ui::EventRewriteStatus EventRewriter::RewriteTouchEvent( |
404 const ui::TouchEvent& touch_event, | 437 const ui::TouchEvent& touch_event, |
405 scoped_ptr<ui::Event>* rewritten_event) { | 438 scoped_ptr<ui::Event>* rewritten_event) { |
406 int flags = touch_event.flags(); | 439 int flags = touch_event.flags(); |
407 RewriteLocatedEvent(touch_event, &flags); | 440 RewriteLocatedEvent(touch_event, &flags); |
408 if (touch_event.flags() == flags) | 441 if (touch_event.flags() == flags) |
409 return ui::EVENT_REWRITE_CONTINUE; | 442 return ui::EVENT_REWRITE_CONTINUE; |
410 ui::TouchEvent* rewritten_touch_event = new ui::TouchEvent(touch_event); | 443 ui::TouchEvent* rewritten_touch_event = new ui::TouchEvent(touch_event); |
411 rewritten_event->reset(rewritten_touch_event); | 444 rewritten_event->reset(rewritten_touch_event); |
412 rewritten_touch_event->set_flags(flags); | 445 rewritten_touch_event->set_flags(flags); |
413 #if defined(USE_X11) | 446 #if defined(USE_X11) |
414 XEvent* xev = rewritten_touch_event->native_event(); | 447 XEvent* xev = rewritten_touch_event->native_event(); |
415 if (xev) { | 448 if (xev) { |
416 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); | 449 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); |
417 if (xievent) { | 450 if (xievent) { |
418 UpdateX11EventMask( | 451 UpdateX11EventMask( |
419 rewritten_touch_event->flags(), | 452 rewritten_touch_event->flags(), |
420 reinterpret_cast<unsigned int*>(&xievent->mods.effective)); | 453 reinterpret_cast<unsigned int*>(&xievent->mods.effective)); |
421 } | 454 } |
422 } | 455 } |
423 #endif | 456 #endif |
424 return ui::EVENT_REWRITE_REWRITTEN; | 457 return ui::EVENT_REWRITE_REWRITTEN; |
425 } | 458 } |
426 | 459 |
460 ui::EventRewriteStatus EventRewriter::RewriteScrollEvent( | |
461 const ui::ScrollEvent& scroll_event, | |
462 scoped_ptr<ui::Event>* rewritten_event) { | |
463 int flags = scroll_event.flags(); | |
464 ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE; | |
465 if (sticky_keys_controller_) | |
466 status = sticky_keys_controller_->RewriteScrollEvent(scroll_event, &flags); | |
467 if (status == ui::EVENT_REWRITE_CONTINUE) | |
468 return status; | |
469 ui::ScrollEvent* rewritten_scroll_event = new ui::ScrollEvent(scroll_event); | |
470 rewritten_event->reset(rewritten_scroll_event); | |
471 rewritten_scroll_event->set_flags(flags); | |
472 #if defined(USE_X11) | |
473 XEvent* xev = rewritten_scroll_event->native_event(); | |
474 if (xev) { | |
475 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); | |
476 if (xievent) { | |
477 UpdateX11EventMask( | |
478 rewritten_scroll_event->flags(), | |
479 reinterpret_cast<unsigned int*>(&xievent->mods.effective)); | |
480 } | |
481 } | |
482 #endif | |
483 return status; | |
484 } | |
485 | |
427 void EventRewriter::RewriteModifierKeys(const ui::KeyEvent& key_event, | 486 void EventRewriter::RewriteModifierKeys(const ui::KeyEvent& key_event, |
428 MutableKeyState* state) { | 487 MutableKeyState* state) { |
429 DCHECK(key_event.type() == ui::ET_KEY_PRESSED || | 488 DCHECK(key_event.type() == ui::ET_KEY_PRESSED || |
430 key_event.type() == ui::ET_KEY_RELEASED); | 489 key_event.type() == ui::ET_KEY_RELEASED); |
431 | 490 |
432 // Do nothing if we have just logged in as guest but have not restarted chrome | 491 // Do nothing if we have just logged in as guest but have not restarted chrome |
433 // process yet (so we are still on the login screen). In this situations we | 492 // process yet (so we are still on the login screen). In this situations we |
434 // have no user profile so can not do anything useful. | 493 // have no user profile so can not do anything useful. |
435 // Note that currently, unlike other accounts, when user logs in as guest, we | 494 // Note that currently, unlike other accounts, when user logs in as guest, we |
436 // restart chrome process. In future this is to be changed. | 495 // restart chrome process. In future this is to be changed. |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
814 | 873 |
815 XIFreeDeviceInfo(device_info); | 874 XIFreeDeviceInfo(device_info); |
816 } | 875 } |
817 | 876 |
818 void EventRewriter::DeviceRemoved(int device_id) { | 877 void EventRewriter::DeviceRemoved(int device_id) { |
819 device_id_to_type_.erase(device_id); | 878 device_id_to_type_.erase(device_id); |
820 } | 879 } |
821 #endif | 880 #endif |
822 | 881 |
823 } // namespace chromeos | 882 } // namespace chromeos |
OLD | NEW |