1 /*
2  * The Wine project - Xinput Joystick Library
3  * Copyright 2008 Andrew Fenn
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19 
20 #include <config.h>
21 //#include <assert.h>
22 //#include <stdarg.h>
23 //#include <string.h>
24 
25 #include <wine/debug.h>
26 //#include "windef.h"
27 #include <winbase.h>
28 //#include "winerror.h"
29 
30 #include <xinput.h>
31 
32 /* Not defined in the headers, used only by XInputGetStateEx */
33 #define XINPUT_GAMEPAD_GUIDE 0x0400
34 
35 WINE_DEFAULT_DEBUG_CHANNEL(xinput);
36 
37 struct
38 {
39     BOOL connected;
40 } controllers[XUSER_MAX_COUNT];
41 
DllMain(HINSTANCE inst,DWORD reason,LPVOID reserved)42 BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved)
43 {
44     switch(reason)
45     {
46     case DLL_PROCESS_ATTACH:
47         DisableThreadLibraryCalls(inst);
48         break;
49     }
50     return TRUE;
51 }
52 
XInputEnable(BOOL enable)53 void WINAPI DECLSPEC_HOTPATCH XInputEnable(BOOL enable)
54 {
55     /* Setting to false will stop messages from XInputSetState being sent
56     to the controllers. Setting to true will send the last vibration
57     value (sent to XInputSetState) to the controller and allow messages to
58     be sent */
59     FIXME("(enable %d) Stub!\n", enable);
60 }
61 
XInputSetState(DWORD index,XINPUT_VIBRATION * vibration)62 DWORD WINAPI XInputSetState(DWORD index, XINPUT_VIBRATION* vibration)
63 {
64     FIXME("(index %u, vibration %p) Stub!\n", index, vibration);
65 
66     if (index >= XUSER_MAX_COUNT)
67         return ERROR_BAD_ARGUMENTS;
68     if (!controllers[index].connected)
69         return ERROR_DEVICE_NOT_CONNECTED;
70 
71     return ERROR_NOT_SUPPORTED;
72 }
73 
XInputGetState(DWORD index,XINPUT_STATE * state)74 DWORD WINAPI DECLSPEC_HOTPATCH XInputGetState(DWORD index, XINPUT_STATE* state)
75 {
76     union
77     {
78         XINPUT_STATE state;
79         XINPUT_STATE_EX state_ex;
80     } xinput;
81     DWORD ret;
82     static int warn_once;
83 
84     if (!warn_once++)
85         FIXME("(index %u, state %p) Stub!\n", index, state);
86 
87     ret = XInputGetStateEx(index, &xinput.state_ex);
88     if (ret != ERROR_SUCCESS)
89         return ret;
90 
91     /* The main difference between this and the Ex version is the media guide button */
92     xinput.state.Gamepad.wButtons &= ~XINPUT_GAMEPAD_GUIDE;
93     *state = xinput.state;
94 
95     return ERROR_SUCCESS;
96 }
97 
XInputGetStateEx(DWORD index,XINPUT_STATE_EX * state_ex)98 DWORD WINAPI DECLSPEC_HOTPATCH XInputGetStateEx(DWORD index, XINPUT_STATE_EX* state_ex)
99 {
100     static int warn_once;
101 
102     if (!warn_once++)
103         FIXME("(index %u, state %p) Stub!\n", index, state_ex);
104 
105     if (index >= XUSER_MAX_COUNT)
106         return ERROR_BAD_ARGUMENTS;
107     if (!controllers[index].connected)
108         return ERROR_DEVICE_NOT_CONNECTED;
109 
110     return ERROR_NOT_SUPPORTED;
111 }
112 
XInputGetKeystroke(DWORD index,DWORD reserved,PXINPUT_KEYSTROKE keystroke)113 DWORD WINAPI XInputGetKeystroke(DWORD index, DWORD reserved, PXINPUT_KEYSTROKE keystroke)
114 {
115     static int warn_once;
116 
117     if (!warn_once++)
118         FIXME("(index %u, reserved %u, keystroke %p) Stub!\n", index, reserved, keystroke);
119 
120     if (index >= XUSER_MAX_COUNT)
121         return ERROR_BAD_ARGUMENTS;
122     if (!controllers[index].connected)
123         return ERROR_DEVICE_NOT_CONNECTED;
124 
125     return ERROR_NOT_SUPPORTED;
126 }
127 
XInputGetCapabilities(DWORD index,DWORD flags,XINPUT_CAPABILITIES * capabilities)128 DWORD WINAPI XInputGetCapabilities(DWORD index, DWORD flags, XINPUT_CAPABILITIES* capabilities)
129 {
130     static int warn_once;
131 
132     if (!warn_once++)
133         FIXME("(index %u, flags 0x%x, capabilities %p) Stub!\n", index, flags, capabilities);
134 
135     if (index >= XUSER_MAX_COUNT)
136         return ERROR_BAD_ARGUMENTS;
137     if (!controllers[index].connected)
138         return ERROR_DEVICE_NOT_CONNECTED;
139 
140     return ERROR_NOT_SUPPORTED;
141 }
142 
XInputGetDSoundAudioDeviceGuids(DWORD index,GUID * render_guid,GUID * capture_guid)143 DWORD WINAPI XInputGetDSoundAudioDeviceGuids(DWORD index, GUID* render_guid, GUID* capture_guid)
144 {
145     FIXME("(index %u, render guid %p, capture guid %p) Stub!\n", index, render_guid, capture_guid);
146 
147     if (index >= XUSER_MAX_COUNT)
148         return ERROR_BAD_ARGUMENTS;
149     if (!controllers[index].connected)
150         return ERROR_DEVICE_NOT_CONNECTED;
151 
152     return ERROR_NOT_SUPPORTED;
153 }
154 
XInputGetBatteryInformation(DWORD index,BYTE type,XINPUT_BATTERY_INFORMATION * battery)155 DWORD WINAPI XInputGetBatteryInformation(DWORD index, BYTE type, XINPUT_BATTERY_INFORMATION* battery)
156 {
157     FIXME("(index %u, type %u, battery %p) Stub!\n", index, type, battery);
158 
159     if (index >= XUSER_MAX_COUNT)
160         return ERROR_BAD_ARGUMENTS;
161     if (!controllers[index].connected)
162         return ERROR_DEVICE_NOT_CONNECTED;
163 
164     return ERROR_NOT_SUPPORTED;
165 }
166