gamepad_device_mac.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // Copyright (c) 2018 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. #ifndef DEVICE_GAMEPAD_GAMEPAD_DEVICE_MAC_H_
  5. #define DEVICE_GAMEPAD_GAMEPAD_DEVICE_MAC_H_
  6. #include <stddef.h>
  7. #include <CoreFoundation/CoreFoundation.h>
  8. #include <ForceFeedback/ForceFeedback.h>
  9. #include <IOKit/hid/IOHIDManager.h>
  10. #include "base/memory/weak_ptr.h"
  11. #include "device/gamepad/abstract_haptic_gamepad.h"
  12. #include "device/gamepad/gamepad_standard_mappings.h"
  13. #include "device/gamepad/public/cpp/gamepad.h"
  14. namespace device {
  15. class Dualshock4Controller;
  16. class HidHapticGamepad;
  17. class XboxHidController;
  18. // GamepadDeviceMac represents a single gamepad device. Gamepad enumeration
  19. // and state polling is handled through the raw HID interface, while haptics
  20. // commands are issued through the ForceFeedback framework.
  21. //
  22. // Dualshock4 haptics are not supported through ForceFeedback and are instead
  23. // sent through the raw HID interface.
  24. class GamepadDeviceMac final : public AbstractHapticGamepad {
  25. public:
  26. GamepadDeviceMac(int location_id,
  27. IOHIDDeviceRef device_ref,
  28. base::StringPiece product_name,
  29. int vendor_id,
  30. int product_id);
  31. ~GamepadDeviceMac() override;
  32. // Initialize |gamepad| with the number of buttons and axes described in the
  33. // device's elements array.
  34. bool AddButtonsAndAxes(Gamepad* gamepad);
  35. // Update the button and axis state in |gamepad| with the new data in |value|.
  36. // If the updated element is an axis, the axis value will first be normalized.
  37. void UpdateGamepadForValue(IOHIDValueRef value, Gamepad* gamepad);
  38. // Return the OS-assigned ID for this device.
  39. int GetLocationId() { return location_id_; }
  40. // Return true if |device| refers to this device.
  41. bool IsSameDevice(IOHIDDeviceRef device) { return device == device_ref_; }
  42. // Return true if this device supports force feedback through the
  43. // ForceFeedback framework.
  44. bool SupportsVibration();
  45. // AbstractHapticGamepad public implementation.
  46. void SetVibration(mojom::GamepadEffectParametersPtr params) override;
  47. void SetZeroVibration() override;
  48. base::WeakPtr<AbstractHapticGamepad> GetWeakPtr() override;
  49. private:
  50. // AbstractHapticGamepad private implementation.
  51. void DoShutdown() override;
  52. // Initialize button capabilities for |gamepad|.
  53. bool AddButtons(Gamepad* gamepad);
  54. // Initialize axis capabilities for |gamepad|.
  55. bool AddAxes(Gamepad* gamepad);
  56. // Return true if this element has a parent collection with a usage page that
  57. // suggests it could be a gamepad.
  58. static bool CheckCollection(IOHIDElementRef element);
  59. // Create a force feedback device node for controlling haptics on
  60. // |device_ref|. Ownership of the returned reference is retained by the
  61. // caller.
  62. static FFDeviceObjectReference CreateForceFeedbackDevice(
  63. IOHIDDeviceRef device_ref);
  64. // Create a force feedback effect on |ff_device_ref| and store the description
  65. // to |ff_effect|. Ownership of the returned reference is retained by the
  66. // caller.
  67. static FFEffectObjectReference CreateForceFeedbackEffect(
  68. FFDeviceObjectReference ff_device_ref,
  69. FFEFFECT* ff_effect,
  70. FFCUSTOMFORCE* ff_custom_force,
  71. LONG* force_data,
  72. DWORD* axes_data,
  73. LONG* direction_data);
  74. int location_id_;
  75. IOHIDDeviceRef device_ref_;
  76. GamepadBusType bus_type_;
  77. IOHIDElementRef button_elements_[Gamepad::kButtonsLengthCap];
  78. IOHIDElementRef axis_elements_[Gamepad::kAxesLengthCap];
  79. CFIndex axis_minimums_[Gamepad::kAxesLengthCap];
  80. CFIndex axis_maximums_[Gamepad::kAxesLengthCap];
  81. CFIndex axis_report_sizes_[Gamepad::kAxesLengthCap];
  82. // Force feedback
  83. FFDeviceObjectReference ff_device_ref_;
  84. FFEffectObjectReference ff_effect_ref_;
  85. FFEFFECT ff_effect_;
  86. FFCUSTOMFORCE ff_custom_force_;
  87. LONG force_data_[2];
  88. DWORD axes_data_[2];
  89. LONG direction_data_[2];
  90. // Dualshock4 functionality, if available.
  91. std::unique_ptr<Dualshock4Controller> dualshock4_;
  92. // Xbox Wireless Controller behaves like a HID gamepad when connected over
  93. // Bluetooth. In this mode, haptics functionality is provided by |xbox_hid_|.
  94. // When connected over USB, Xbox Wireless Controller is supported through
  95. // XboxDataFetcher.
  96. std::unique_ptr<XboxHidController> xbox_hid_;
  97. // A controller that uses a HID output report for vibration effects.
  98. std::unique_ptr<HidHapticGamepad> hid_haptics_;
  99. base::WeakPtrFactory<GamepadDeviceMac> weak_factory_{this};
  100. };
  101. } // namespace device
  102. #endif // DEVICE_GAMEPAD_GAMEPAD_DEVICE_MAC_H_