source: trunk/src/dinput/dinput_main.c@ 8706

Last change on this file since 8706 was 8346, checked in by sandervl, 23 years ago

Resync with last X11 licensed Wine

File size: 8.9 KB
Line 
1/* DirectInput
2 *
3 * Copyright 1998 Marcus Meissner
4 * Copyright 1998,1999 Lionel Ulmer
5 *
6 */
7/* Status:
8 *
9 * - Tomb Raider 2 Demo:
10 * Playable using keyboard only.
11 * - WingCommander Prophecy Demo:
12 * Doesn't get Input Focus.
13 *
14 * - Fallout : works great in X and DGA mode
15 *
16 * FIXME: The keyboard handling needs to (and will) be merged into keyboard.c
17 * (The current implementation is currently only a proof of concept and
18 * an utter mess.)
19 */
20
21#include "config.h"
22#include <assert.h>
23#include <string.h>
24
25#include "debugtools.h"
26#include "winbase.h"
27#include "winerror.h"
28#include "windef.h"
29#include "dinput_private.h"
30
31DEFAULT_DEBUG_CHANNEL(dinput);
32
33static ICOM_VTABLE(IDirectInputA) ddiavt;
34static ICOM_VTABLE(IDirectInput7A) ddi7avt;
35
36/* This array will be filled a dinput.so loading */
37#define MAX_WINE_DINPUT_DEVICES 4
38static dinput_device * dinput_devices[MAX_WINE_DINPUT_DEVICES];
39static int nrof_dinput_devices = 0;
40
41/* register a direct draw driver. We better not use malloc for we are in
42 * the ELF startup initialisation at this point.
43 */
44void dinput_register_device(dinput_device *device) {
45 int i;
46
47 /* insert according to priority */
48 for (i=0;i<nrof_dinput_devices;i++) {
49 if (dinput_devices[i]->pref <= device->pref) {
50 memcpy(dinput_devices+i+1,dinput_devices+i,sizeof(dinput_devices[0])*(nrof_dinput_devices-i));
51 dinput_devices[i] = device;
52 break;
53 }
54 }
55 if (i==nrof_dinput_devices) /* not found, or too low priority */
56 dinput_devices[nrof_dinput_devices] = device;
57
58 nrof_dinput_devices++;
59
60 /* increase MAX_DDRAW_DRIVERS if the line below triggers */
61 assert(nrof_dinput_devices <= MAX_WINE_DINPUT_DEVICES);
62}
63
64/******************************************************************************
65 * DirectInputCreateEx (DINPUT.@)
66 */
67HRESULT WINAPI DirectInputCreateEx(
68 HINSTANCE hinst, DWORD dwVersion, REFIID riid, LPVOID *ppDI,
69 LPUNKNOWN punkOuter
70) {
71 IDirectInputAImpl* This;
72
73 TRACE("(0x%08lx,%04lx,%s,%p,%p)\n",
74 (DWORD)hinst,dwVersion,debugstr_guid(riid),ppDI,punkOuter
75 );
76 if (IsEqualGUID(&IID_IDirectInputA,riid)) {
77 This = (IDirectInputAImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputAImpl));
78 This->ref = 1;
79 ICOM_VTBL(This) = &ddiavt;
80 *ppDI = This;
81
82 return DI_OK;
83 }
84
85 if (IsEqualGUID(&IID_IDirectInput7A,riid)) {
86 This = (IDirectInputAImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputAImpl));
87 This->ref = 1;
88 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectInputA) *) &ddi7avt;
89 *ppDI = This;
90
91 return DI_OK;
92 }
93
94 return DIERR_OLDDIRECTINPUTVERSION;
95}
96
97/******************************************************************************
98 * DirectInputCreateA (DINPUT.@)
99 */
100HRESULT WINAPI DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTA *ppDI, LPUNKNOWN punkOuter)
101{
102 IDirectInputAImpl* This;
103 TRACE("(0x%08lx,%04lx,%p,%p)\n",
104 (DWORD)hinst,dwVersion,ppDI,punkOuter
105 );
106 This = (IDirectInputAImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputAImpl));
107 This->ref = 1;
108 ICOM_VTBL(This) = &ddiavt;
109 *ppDI=(IDirectInputA*)This;
110 return 0;
111}
112/******************************************************************************
113 * IDirectInputA_EnumDevices
114 */
115static HRESULT WINAPI IDirectInputAImpl_EnumDevices(
116 LPDIRECTINPUT7A iface, DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback,
117 LPVOID pvRef, DWORD dwFlags
118)
119{
120 ICOM_THIS(IDirectInputAImpl,iface);
121 DIDEVICEINSTANCEA devInstance;
122 int i;
123
124 TRACE("(this=%p,0x%04lx,%p,%p,%04lx)\n", This, dwDevType, lpCallback, pvRef, dwFlags);
125
126 for (i = 0; i < nrof_dinput_devices; i++) {
127 if (dinput_devices[i]->enum_device(dwDevType, dwFlags, &devInstance)) {
128 if (lpCallback(&devInstance,pvRef) == DIENUM_STOP)
129 return 0;
130 }
131 }
132
133 return 0;
134}
135
136static ULONG WINAPI IDirectInputAImpl_AddRef(LPDIRECTINPUT7A iface)
137{
138 ICOM_THIS(IDirectInputAImpl,iface);
139 return ++(This->ref);
140}
141
142static ULONG WINAPI IDirectInputAImpl_Release(LPDIRECTINPUT7A iface)
143{
144 ICOM_THIS(IDirectInputAImpl,iface);
145 if (!(--This->ref)) {
146 HeapFree(GetProcessHeap(),0,This);
147 return 0;
148 }
149 return This->ref;
150}
151
152static HRESULT WINAPI IDirectInputAImpl_CreateDevice(
153 LPDIRECTINPUT7A iface,REFGUID rguid,LPDIRECTINPUTDEVICEA* pdev,
154 LPUNKNOWN punk
155) {
156 ICOM_THIS(IDirectInputAImpl,iface);
157 HRESULT ret_value = DIERR_DEVICENOTREG;
158 int i;
159
160 TRACE("(this=%p,%s,%p,%p)\n",This,debugstr_guid(rguid),pdev,punk);
161
162 /* Loop on all the devices to see if anyone matches the given GUID */
163 for (i = 0; i < nrof_dinput_devices; i++) {
164 HRESULT ret;
165 if ((ret = dinput_devices[i]->create_device(This, rguid, NULL, pdev)) == DI_OK)
166 return DI_OK;
167
168 if (ret == DIERR_NOINTERFACE)
169 ret_value = DIERR_NOINTERFACE;
170 }
171
172 return ret_value;
173}
174
175static HRESULT WINAPI IDirectInputAImpl_QueryInterface(
176 LPDIRECTINPUT7A iface,REFIID riid,LPVOID *ppobj
177) {
178 ICOM_THIS(IDirectInputAImpl,iface);
179
180 TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
181 if (IsEqualGUID(&IID_IUnknown,riid)) {
182 IDirectInputA_AddRef(iface);
183 *ppobj = This;
184 return 0;
185 }
186 if (IsEqualGUID(&IID_IDirectInputA,riid)) {
187 IDirectInputA_AddRef(iface);
188 *ppobj = This;
189 return 0;
190 }
191 TRACE("Unsupported interface !\n");
192 return E_FAIL;
193}
194
195static HRESULT WINAPI IDirectInputAImpl_Initialize(
196 LPDIRECTINPUT7A iface,HINSTANCE hinst,DWORD x
197) {
198 return DIERR_ALREADYINITIALIZED;
199}
200
201static HRESULT WINAPI IDirectInputAImpl_GetDeviceStatus(LPDIRECTINPUT7A iface,
202 REFGUID rguid) {
203 ICOM_THIS(IDirectInputAImpl,iface);
204
205 FIXME("(%p)->(%s): stub\n",This,debugstr_guid(rguid));
206
207 return DI_OK;
208}
209
210static HRESULT WINAPI IDirectInputAImpl_RunControlPanel(LPDIRECTINPUT7A iface,
211 HWND hwndOwner,
212 DWORD dwFlags) {
213 ICOM_THIS(IDirectInputAImpl,iface);
214 FIXME("(%p)->(%08lx,%08lx): stub\n",This, (DWORD) hwndOwner, dwFlags);
215
216 return DI_OK;
217}
218
219static HRESULT WINAPI IDirectInput2AImpl_FindDevice(LPDIRECTINPUT2A iface, REFGUID rguid,
220 LPCSTR pszName, LPGUID pguidInstance) {
221 ICOM_THIS(IDirectInputAImpl,iface);
222 FIXME("(%p)->(%s, %s, %p): stub\n", This, debugstr_guid(rguid), pszName, pguidInstance);
223
224 return DI_OK;
225}
226
227static HRESULT WINAPI IDirectInput7AImpl_CreateDeviceEx(LPDIRECTINPUT7A iface, REFGUID rguid,
228 REFIID riid, LPVOID* pvOut, LPUNKNOWN lpUnknownOuter)
229{
230 ICOM_THIS(IDirectInputAImpl,iface);
231 HRESULT ret_value = DIERR_DEVICENOTREG;
232 int i;
233
234 TRACE("(%p)->(%s, %s, %p, %p)\n", This, debugstr_guid(rguid), debugstr_guid(riid), pvOut, lpUnknownOuter);
235
236 /* Loop on all the devices to see if anyone matches the given GUID */
237 for (i = 0; i < nrof_dinput_devices; i++) {
238 HRESULT ret;
239 if ((ret = dinput_devices[i]->create_device(This, rguid, riid, (LPDIRECTINPUTDEVICEA*) pvOut)) == DI_OK)
240 return DI_OK;
241
242 if (ret == DIERR_NOINTERFACE)
243 ret_value = DIERR_NOINTERFACE;
244 }
245
246 return ret_value;
247}
248
249#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
250# define XCAST(fun) (typeof(ddiavt.fun))
251#else
252# define XCAST(fun) (void*)
253#endif
254
255static ICOM_VTABLE(IDirectInputA) ddiavt =
256{
257 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
258 XCAST(QueryInterface)IDirectInputAImpl_QueryInterface,
259 XCAST(AddRef)IDirectInputAImpl_AddRef,
260 XCAST(Release)IDirectInputAImpl_Release,
261 XCAST(CreateDevice)IDirectInputAImpl_CreateDevice,
262 XCAST(EnumDevices)IDirectInputAImpl_EnumDevices,
263 XCAST(GetDeviceStatus)IDirectInputAImpl_GetDeviceStatus,
264 XCAST(RunControlPanel)IDirectInputAImpl_RunControlPanel,
265 XCAST(Initialize)IDirectInputAImpl_Initialize
266};
267#undef XCAST
268
269#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
270# define XCAST(fun) (typeof(ddi7avt.fun))
271#else
272# define XCAST(fun) (void*)
273#endif
274
275static ICOM_VTABLE(IDirectInput7A) ddi7avt = {
276 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
277 XCAST(QueryInterface)IDirectInputAImpl_QueryInterface,
278 XCAST(AddRef)IDirectInputAImpl_AddRef,
279 XCAST(Release)IDirectInputAImpl_Release,
280 XCAST(CreateDevice)IDirectInputAImpl_CreateDevice,
281 XCAST(EnumDevices)IDirectInputAImpl_EnumDevices,
282 XCAST(GetDeviceStatus)IDirectInputAImpl_GetDeviceStatus,
283 XCAST(RunControlPanel)IDirectInputAImpl_RunControlPanel,
284 XCAST(Initialize)IDirectInputAImpl_Initialize,
285 XCAST(FindDevice)IDirectInput2AImpl_FindDevice,
286 IDirectInput7AImpl_CreateDeviceEx
287};
288#undef XCAST
289
290/***********************************************************************
291 * DllCanUnloadNow (DINPUT.@)
292 */
293HRESULT WINAPI DINPUT_DllCanUnloadNow(void)
294{
295 FIXME("(void): stub\n");
296
297 return S_FALSE;
298}
299
300/***********************************************************************
301 * DllGetClassObject (DINPUT.@)
302 */
303HRESULT WINAPI DINPUT_DllGetClassObject(REFCLSID rclsid, REFIID riid,
304 LPVOID *ppv)
305{
306 FIXME("(%p, %p, %p): stub\n", debugstr_guid(rclsid),
307 debugstr_guid(riid), ppv);
308
309 return CLASS_E_CLASSNOTAVAILABLE;
310}
311
312/***********************************************************************
313 * DllRegisterServer (DINPUT.@)
314 */
315HRESULT WINAPI DINPUT_DllRegisterServer(void)
316{
317 FIXME("(void): stub\n");
318
319 return S_OK;
320}
321
322/***********************************************************************
323 * DllUnregisterServer (DINPUT.@)
324 */
325HRESULT WINAPI DINPUT_DllUnregisterServer(void)
326{
327 FIXME("(void): stub\n");
328
329 return S_OK;
330}
Note: See TracBrowser for help on using the repository browser.