3 * Copyright 1998 Marcus Meissner
4 * Copyright 1998,1999 Lionel Ulmer
9 * - Tomb Raider 2 Demo:
10 * Playable using keyboard only.
11 * - WingCommander Prophecy Demo:
12 * Doesn't get Input Focus.
14 * - Fallout : works great in X and DGA mode
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
25 #include "debugtools.h"
29 #include "dinput_private.h"
31 DEFAULT_DEBUG_CHANNEL(dinput);
33 static ICOM_VTABLE(IDirectInputA) ddiavt;
34 static ICOM_VTABLE(IDirectInput7A) ddi7avt;
36 /* This array will be filled a dinput.so loading */
37 #define MAX_WINE_DINPUT_DEVICES 4
38 static dinput_device * dinput_devices[MAX_WINE_DINPUT_DEVICES];
39 static int nrof_dinput_devices = 0;
41 /* register a direct draw driver. We better not use malloc for we are in
42 * the ELF startup initialisation at this point.
44 void dinput_register_device(dinput_device *device) {
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;
55 if (i==nrof_dinput_devices) /* not found, or too low priority */
56 dinput_devices[nrof_dinput_devices] = device;
58 nrof_dinput_devices++;
60 /* increase MAX_DDRAW_DRIVERS if the line below triggers */
61 assert(nrof_dinput_devices <= MAX_WINE_DINPUT_DEVICES);
64 /******************************************************************************
65 * DirectInputCreateEx (DINPUT.@)
67 HRESULT WINAPI DirectInputCreateEx(
68 HINSTANCE hinst, DWORD dwVersion, REFIID riid, LPVOID *ppDI,
71 IDirectInputAImpl* This;
73 TRACE("(0x%08lx,%04lx,%s,%p,%p)\n",
74 (DWORD)hinst,dwVersion,debugstr_guid(riid),ppDI,punkOuter
76 if (IsEqualGUID(&IID_IDirectInputA,riid)) {
77 This = (IDirectInputAImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputAImpl));
79 ICOM_VTBL(This) = &ddiavt;
85 if (IsEqualGUID(&IID_IDirectInput7A,riid)) {
86 This = (IDirectInputAImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputAImpl));
88 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectInputA) *) &ddi7avt;
94 return DIERR_OLDDIRECTINPUTVERSION;
97 /******************************************************************************
98 * DirectInputCreateA (DINPUT.@)
100 HRESULT WINAPI DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTA *ppDI, LPUNKNOWN punkOuter)
102 IDirectInputAImpl* This;
103 TRACE("(0x%08lx,%04lx,%p,%p)\n",
104 (DWORD)hinst,dwVersion,ppDI,punkOuter
106 This = (IDirectInputAImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputAImpl));
108 ICOM_VTBL(This) = &ddiavt;
109 *ppDI=(IDirectInputA*)This;
112 /******************************************************************************
113 * IDirectInputA_EnumDevices
115 static HRESULT WINAPI IDirectInputAImpl_EnumDevices(
116 LPDIRECTINPUT7A iface, DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback,
117 LPVOID pvRef, DWORD dwFlags
120 ICOM_THIS(IDirectInputAImpl,iface);
121 DIDEVICEINSTANCEA devInstance;
124 TRACE("(this=%p,0x%04lx,%p,%p,%04lx)\n", This, dwDevType, lpCallback, pvRef, dwFlags);
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)
136 static ULONG WINAPI IDirectInputAImpl_AddRef(LPDIRECTINPUT7A iface)
138 ICOM_THIS(IDirectInputAImpl,iface);
139 return ++(This->ref);
142 static ULONG WINAPI IDirectInputAImpl_Release(LPDIRECTINPUT7A iface)
144 ICOM_THIS(IDirectInputAImpl,iface);
145 if (!(--This->ref)) {
146 HeapFree(GetProcessHeap(),0,This);
152 static HRESULT WINAPI IDirectInputAImpl_CreateDevice(
153 LPDIRECTINPUT7A iface,REFGUID rguid,LPDIRECTINPUTDEVICEA* pdev,
156 ICOM_THIS(IDirectInputAImpl,iface);
157 HRESULT ret_value = DIERR_DEVICENOTREG;
160 TRACE("(this=%p,%s,%p,%p)\n",This,debugstr_guid(rguid),pdev,punk);
162 /* Loop on all the devices to see if anyone matches the given GUID */
163 for (i = 0; i < nrof_dinput_devices; i++) {
165 if ((ret = dinput_devices[i]->create_device(This, rguid, NULL, pdev)) == DI_OK)
168 if (ret == DIERR_NOINTERFACE)
169 ret_value = DIERR_NOINTERFACE;
175 static HRESULT WINAPI IDirectInputAImpl_QueryInterface(
176 LPDIRECTINPUT7A iface,REFIID riid,LPVOID *ppobj
178 ICOM_THIS(IDirectInputAImpl,iface);
180 TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
181 if (IsEqualGUID(&IID_IUnknown,riid)) {
182 IDirectInputA_AddRef(iface);
186 if (IsEqualGUID(&IID_IDirectInputA,riid)) {
187 IDirectInputA_AddRef(iface);
191 TRACE("Unsupported interface !\n");
195 static HRESULT WINAPI IDirectInputAImpl_Initialize(
196 LPDIRECTINPUT7A iface,HINSTANCE hinst,DWORD x
198 return DIERR_ALREADYINITIALIZED;
201 static HRESULT WINAPI IDirectInputAImpl_GetDeviceStatus(LPDIRECTINPUT7A iface,
203 ICOM_THIS(IDirectInputAImpl,iface);
205 FIXME("(%p)->(%s): stub\n",This,debugstr_guid(rguid));
210 static HRESULT WINAPI IDirectInputAImpl_RunControlPanel(LPDIRECTINPUT7A iface,
213 ICOM_THIS(IDirectInputAImpl,iface);
214 FIXME("(%p)->(%08lx,%08lx): stub\n",This, (DWORD) hwndOwner, dwFlags);
219 static 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);
227 static HRESULT WINAPI IDirectInput7AImpl_CreateDeviceEx(LPDIRECTINPUT7A iface, REFGUID rguid,
228 REFIID riid, LPVOID* pvOut, LPUNKNOWN lpUnknownOuter)
230 ICOM_THIS(IDirectInputAImpl,iface);
231 HRESULT ret_value = DIERR_DEVICENOTREG;
234 TRACE("(%p)->(%s, %s, %p, %p)\n", This, debugstr_guid(rguid), debugstr_guid(riid), pvOut, lpUnknownOuter);
236 /* Loop on all the devices to see if anyone matches the given GUID */
237 for (i = 0; i < nrof_dinput_devices; i++) {
239 if ((ret = dinput_devices[i]->create_device(This, rguid, riid, (LPDIRECTINPUTDEVICEA*) pvOut)) == DI_OK)
242 if (ret == DIERR_NOINTERFACE)
243 ret_value = DIERR_NOINTERFACE;
249 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
250 # define XCAST(fun) (typeof(ddiavt.fun))
252 # define XCAST(fun) (void*)
255 static ICOM_VTABLE(IDirectInputA) ddiavt =
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
269 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
270 # define XCAST(fun) (typeof(ddi7avt.fun))
272 # define XCAST(fun) (void*)
275 static 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
290 /***********************************************************************
291 * DllCanUnloadNow (DINPUT.@)
293 HRESULT WINAPI DINPUT_DllCanUnloadNow(void)
295 FIXME("(void): stub\n");
300 /***********************************************************************
301 * DllGetClassObject (DINPUT.@)
303 HRESULT WINAPI DINPUT_DllGetClassObject(REFCLSID rclsid, REFIID riid,
306 FIXME("(%p, %p, %p): stub\n", debugstr_guid(rclsid),
307 debugstr_guid(riid), ppv);
309 return CLASS_E_CLASSNOTAVAILABLE;
312 /***********************************************************************
313 * DllRegisterServer (DINPUT.@)
315 HRESULT WINAPI DINPUT_DllRegisterServer(void)
317 FIXME("(void): stub\n");
322 /***********************************************************************
323 * DllUnregisterServer (DINPUT.@)
325 HRESULT WINAPI DINPUT_DllUnregisterServer(void)
327 FIXME("(void): stub\n");