gaming_seat.cc 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/exo/gaming_seat.h"
  5. #include <vector>
  6. #include "components/exo/gamepad.h"
  7. #include "components/exo/gamepad_delegate.h"
  8. #include "components/exo/gaming_seat_delegate.h"
  9. #include "components/exo/shell_surface_util.h"
  10. #include "components/exo/surface.h"
  11. #include "ui/events/ozone/gamepad/gamepad_provider_ozone.h"
  12. namespace exo {
  13. ////////////////////////////////////////////////////////////////////////////////
  14. // GamingSeat, public:
  15. GamingSeat::GamingSeat(GamingSeatDelegate* delegate) : delegate_(delegate) {
  16. auto* helper = WMHelper::GetInstance();
  17. helper->AddFocusObserver(this);
  18. OnWindowFocused(helper->GetFocusedWindow(), nullptr);
  19. }
  20. GamingSeat::~GamingSeat() {
  21. if (focused_)
  22. ui::GamepadProviderOzone::GetInstance()->RemoveGamepadObserver(this);
  23. delegate_->OnGamingSeatDestroying(this);
  24. WMHelper::GetInstance()->RemoveFocusObserver(this);
  25. }
  26. ////////////////////////////////////////////////////////////////////////////////
  27. // ui::aura::client::FocusChangeObserver overrides:
  28. void GamingSeat::OnWindowFocused(aura::Window* gained_focus,
  29. aura::Window* lost_focus) {
  30. Surface* target = nullptr;
  31. if (gained_focus) {
  32. target = Surface::AsSurface(gained_focus);
  33. if (!target) {
  34. aura::Window* top_level_window = gained_focus->GetToplevelWindow();
  35. if (top_level_window)
  36. target = GetShellRootSurface(top_level_window);
  37. }
  38. }
  39. bool focused = target && delegate_->CanAcceptGamepadEventsForSurface(target);
  40. if (focused_ != focused) {
  41. focused_ = focused;
  42. if (focused) {
  43. ui::GamepadProviderOzone::GetInstance()->AddGamepadObserver(this);
  44. OnGamepadDevicesUpdated();
  45. for (auto& entry : gamepads_)
  46. entry.second->OnGamepadFocused();
  47. } else {
  48. ui::GamepadProviderOzone::GetInstance()->RemoveGamepadObserver(this);
  49. for (auto& entry : gamepads_)
  50. entry.second->OnGamepadFocusLost();
  51. }
  52. }
  53. }
  54. ////////////////////////////////////////////////////////////////////////////////
  55. // ui::GamepadObserver overrides:
  56. void GamingSeat::OnGamepadDevicesUpdated() {
  57. std::vector<ui::GamepadDevice> gamepad_devices =
  58. ui::GamepadProviderOzone::GetInstance()->GetGamepadDevices();
  59. base::flat_map<int, std::unique_ptr<Gamepad>> new_gamepads;
  60. // Copy the "still connected gamepads".
  61. for (auto& device : gamepad_devices) {
  62. auto it = gamepads_.find(device.id);
  63. if (it != gamepads_.end()) {
  64. new_gamepads[device.id] = std::move(it->second);
  65. gamepads_.erase(it);
  66. }
  67. }
  68. // Add each new connected gamepad.
  69. for (auto& device : gamepad_devices) {
  70. if (new_gamepads.find(device.id) == new_gamepads.end()) {
  71. std::unique_ptr<Gamepad> gamepad = std::make_unique<Gamepad>(device);
  72. if (focused_)
  73. gamepad->OnGamepadFocused();
  74. delegate_->GamepadAdded(*gamepad);
  75. new_gamepads[device.id] = std::move(gamepad);
  76. }
  77. }
  78. new_gamepads.swap(gamepads_);
  79. }
  80. void GamingSeat::OnGamepadEvent(const ui::GamepadEvent& event) {
  81. auto it = gamepads_.find(event.device_id());
  82. if (it == gamepads_.end())
  83. return;
  84. it->second->OnGamepadEvent(event);
  85. }
  86. } // namespace exo