1 // Copyright (c) 2012 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 
5 #ifndef DEVICE_GAMEPAD_XINPUT_DATA_FETCHER_WIN_H_
6 #define DEVICE_GAMEPAD_XINPUT_DATA_FETCHER_WIN_H_
7 
8 #include <memory>
9 
10 #include "build/build_config.h"
11 
12 #ifndef WIN32_LEAN_AND_MEAN
13 #define WIN32_LEAN_AND_MEAN
14 #endif
15 #include <Unknwn.h>
16 #include <WinDef.h>
17 #include <XInput.h>
18 #include <stdlib.h>
19 #include <windows.h>
20 
21 #include "base/compiler_specific.h"
22 #include "base/macros.h"
23 #include "base/memory/weak_ptr.h"
24 #include "base/scoped_native_library.h"
25 #include "device/gamepad/gamepad_data_fetcher.h"
26 #include "device/gamepad/gamepad_standard_mappings.h"
27 #include "device/gamepad/public/cpp/gamepads.h"
28 #include "device/gamepad/xinput_haptic_gamepad_win.h"
29 
30 namespace device {
31 
32 // XInputGetStateEx uses a slightly larger struct than XInputGetState.
33 struct XInputGamepadEx {
34   WORD wButtons;
35   BYTE bLeftTrigger;
36   BYTE bRightTrigger;
37   SHORT sThumbLX;
38   SHORT sThumbLY;
39   SHORT sThumbRX;
40   SHORT sThumbRY;
41   DWORD dwPaddingReserved;
42 };
43 
44 struct XInputStateEx {
45   DWORD dwPacketNumber;
46   XInputGamepadEx Gamepad;
47 };
48 
49 class XInputDataFetcherWin : public GamepadDataFetcher {
50  public:
51   typedef GamepadDataFetcherFactoryImpl<XInputDataFetcherWin,
52                                         GAMEPAD_SOURCE_WIN_XINPUT>
53       Factory;
54 
55   XInputDataFetcherWin();
56   ~XInputDataFetcherWin() override;
57 
58   GamepadSource source() override;
59 
60   // GamepadDataFetcher implementation.
61   void GetGamepadData(bool devices_changed_hint) override;
62 
63   void PlayEffect(int pad_index,
64                   mojom::GamepadHapticEffectType,
65                   mojom::GamepadEffectParametersPtr,
66                   mojom::GamepadHapticsManager::PlayVibrationEffectOnceCallback,
67                   scoped_refptr<base::SequencedTaskRunner>) override;
68 
69   void ResetVibration(
70       int pad_index,
71       mojom::GamepadHapticsManager::ResetVibrationActuatorCallback,
72       scoped_refptr<base::SequencedTaskRunner>) override;
73 
74  private:
75   void OnAddedToProvider() override;
76 
77   // The function types we use from xinput1_3.dll.
78   typedef void(WINAPI* XInputEnableFunc)(BOOL enable);
79   typedef DWORD(WINAPI* XInputGetCapabilitiesFunc)(
80       DWORD dwUserIndex,
81       DWORD dwFlags,
82       XINPUT_CAPABILITIES* pCapabilities);
83   typedef DWORD(WINAPI* XInputGetStateFunc)(DWORD dwUserIndex,
84                                             XINPUT_STATE* pState);
85   typedef DWORD(WINAPI* XInputGetStateExFunc)(DWORD dwUserIndex,
86                                               XInputStateEx* pState);
87 
88   // Get functions from dynamically loading the xinput dll.
89   // Returns true if loading was successful.
90   bool GetXInputDllFunctions();
91 
92   // Scan for connected XInput and DirectInput gamepads.
93   void EnumerateDevices();
94   void GetXInputPadData(int i);
95 
96   base::ScopedNativeLibrary xinput_dll_;
97   bool xinput_available_;
98 
99   // Function pointers to XInput functionality, retrieved in
100   // |GetXInputDllFunctions|.
101   XInputGetCapabilitiesFunc xinput_get_capabilities_;
102   XInputGetStateFunc xinput_get_state_;
103   XInputGetStateExFunc xinput_get_state_ex_;
104   XInputHapticGamepadWin::XInputSetStateFunc xinput_set_state_;
105 
106   bool xinput_connected_[XUSER_MAX_COUNT];
107   std::unique_ptr<XInputHapticGamepadWin> haptics_[XUSER_MAX_COUNT];
108 
109   DISALLOW_COPY_AND_ASSIGN(XInputDataFetcherWin);
110 };
111 
112 }  // namespace device
113 
114 #endif  // DEVICE_GAMEPAD_XINPUT_DATA_FETCHER_WIN_H_
115