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
24 #include "debugtools.h"
31 #include "dinput_private.h"
33 DEFAULT_DEBUG_CHANNEL(dinput);
35 static ICOM_VTABLE(IDirectInputA) ddiavt;
36 static ICOM_VTABLE(IDirectInput7A) ddi7avt;
38 /* This array will be filled a dinput.so loading */
39 #define MAX_WINE_DINPUT_DEVICES 3
40 static dinput_device * dinput_devices[MAX_WINE_DINPUT_DEVICES];
41 static int nrof_dinput_devices = 0;
43 /* register a direct draw driver. We better not use malloc for we are in
44 * the ELF startup initialisation at this point.
46 void dinput_register_device(dinput_device *device) {
47 dinput_devices[nrof_dinput_devices++] = device;
49 /* increase MAX_DDRAW_DRIVERS if the line below triggers */
50 assert(nrof_dinput_devices <= MAX_WINE_DINPUT_DEVICES);
53 /******************************************************************************
56 HRESULT WINAPI DirectInputCreateEx(
57 HINSTANCE hinst, DWORD dwVersion, REFIID riid, LPVOID *ppDI,
60 IDirectInputAImpl* This;
62 TRACE("(0x%08lx,%04lx,%s,%p,%p)\n",
63 (DWORD)hinst,dwVersion,debugstr_guid(riid),ppDI,punkOuter
65 if (IsEqualGUID(&IID_IDirectInputA,riid)) {
66 This = (IDirectInputAImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputAImpl));
68 ICOM_VTBL(This) = &ddiavt;
74 if (IsEqualGUID(&IID_IDirectInput7A,riid)) {
75 This = (IDirectInputAImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputAImpl));
77 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectInputA) *) &ddi7avt;
83 return DIERR_OLDDIRECTINPUTVERSION;
86 /******************************************************************************
89 HRESULT WINAPI DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTA *ppDI, LPUNKNOWN punkOuter)
91 IDirectInputAImpl* This;
92 TRACE("(0x%08lx,%04lx,%p,%p)\n",
93 (DWORD)hinst,dwVersion,ppDI,punkOuter
95 This = (IDirectInputAImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputAImpl));
97 ICOM_VTBL(This) = &ddiavt;
98 *ppDI=(IDirectInputA*)This;
101 /******************************************************************************
102 * IDirectInputA_EnumDevices
104 static HRESULT WINAPI IDirectInputAImpl_EnumDevices(
105 LPDIRECTINPUTA iface, DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback,
106 LPVOID pvRef, DWORD dwFlags
109 ICOM_THIS(IDirectInputAImpl,iface);
110 DIDEVICEINSTANCEA devInstance;
113 TRACE("(this=%p,0x%04lx,%p,%p,%04lx)\n", This, dwDevType, lpCallback, pvRef, dwFlags);
115 for (i = 0; i < nrof_dinput_devices; i++) {
116 if (dinput_devices[i]->enum_device(dwDevType, dwFlags, &devInstance)) {
117 if (lpCallback(&devInstance,pvRef) == DIENUM_STOP)
125 static ULONG WINAPI IDirectInputAImpl_AddRef(LPDIRECTINPUTA iface)
127 ICOM_THIS(IDirectInputAImpl,iface);
128 return ++(This->ref);
131 static ULONG WINAPI IDirectInputAImpl_Release(LPDIRECTINPUTA iface)
133 ICOM_THIS(IDirectInputAImpl,iface);
134 if (!(--This->ref)) {
135 HeapFree(GetProcessHeap(),0,This);
141 static HRESULT WINAPI IDirectInputAImpl_CreateDevice(
142 LPDIRECTINPUTA iface,REFGUID rguid,LPDIRECTINPUTDEVICEA* pdev,
145 ICOM_THIS(IDirectInputAImpl,iface);
146 HRESULT ret_value = DIERR_DEVICENOTREG;
149 TRACE("(this=%p,%s,%p,%p)\n",This,debugstr_guid(rguid),pdev,punk);
151 /* Loop on all the devices to see if anyone matches the given GUID */
152 for (i = 0; i < nrof_dinput_devices; i++) {
154 if ((ret = dinput_devices[i]->create_device(This, rguid, NULL, pdev)) == DI_OK)
157 if (ret == DIERR_NOINTERFACE)
158 ret_value = DIERR_NOINTERFACE;
164 static HRESULT WINAPI IDirectInputAImpl_QueryInterface(
165 LPDIRECTINPUTA iface,REFIID riid,LPVOID *ppobj
167 ICOM_THIS(IDirectInputAImpl,iface);
169 TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
170 if (IsEqualGUID(&IID_IUnknown,riid)) {
171 IDirectInputA_AddRef(iface);
175 if (IsEqualGUID(&IID_IDirectInputA,riid)) {
176 IDirectInputA_AddRef(iface);
180 TRACE("Unsupported interface !\n");
184 static HRESULT WINAPI IDirectInputAImpl_Initialize(
185 LPDIRECTINPUTA iface,HINSTANCE hinst,DWORD x
187 return DIERR_ALREADYINITIALIZED;
190 static HRESULT WINAPI IDirectInputAImpl_GetDeviceStatus(LPDIRECTINPUTA iface,
192 ICOM_THIS(IDirectInputAImpl,iface);
194 FIXME("(%p)->(%s): stub\n",This,debugstr_guid(rguid));
199 static HRESULT WINAPI IDirectInputAImpl_RunControlPanel(LPDIRECTINPUTA iface,
202 ICOM_THIS(IDirectInputAImpl,iface);
203 FIXME("(%p)->(%08lx,%08lx): stub\n",This, (DWORD) hwndOwner, dwFlags);
208 static HRESULT WINAPI IDirectInput2AImpl_FindDevice(LPDIRECTINPUT2A iface, REFGUID rguid,
209 LPCSTR pszName, LPGUID pguidInstance) {
210 ICOM_THIS(IDirectInputAImpl,iface);
211 FIXME("(%p)->(%s, %s, %p): stub\n", This, debugstr_guid(rguid), pszName, pguidInstance);
216 static HRESULT WINAPI IDirectInput7AImpl_CreateDeviceEx(LPDIRECTINPUT7A iface, REFGUID rguid,
217 REFIID riid, LPVOID* pvOut, LPUNKNOWN lpUnknownOuter)
219 ICOM_THIS(IDirectInputAImpl,iface);
220 HRESULT ret_value = DIERR_DEVICENOTREG;
223 TRACE("(%p)->(%s, %s, %p, %p)\n", This, debugstr_guid(rguid), debugstr_guid(riid), pvOut, lpUnknownOuter);
225 /* Loop on all the devices to see if anyone matches the given GUID */
226 for (i = 0; i < nrof_dinput_devices; i++) {
228 if ((ret = dinput_devices[i]->create_device(This, rguid, riid, (LPDIRECTINPUTDEVICEA*) pvOut)) == DI_OK)
231 if (ret == DIERR_NOINTERFACE)
232 ret_value = DIERR_NOINTERFACE;
238 static ICOM_VTABLE(IDirectInputA) ddiavt =
240 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
241 IDirectInputAImpl_QueryInterface,
242 IDirectInputAImpl_AddRef,
243 IDirectInputAImpl_Release,
244 IDirectInputAImpl_CreateDevice,
245 IDirectInputAImpl_EnumDevices,
246 IDirectInputAImpl_GetDeviceStatus,
247 IDirectInputAImpl_RunControlPanel,
248 IDirectInputAImpl_Initialize
251 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
252 # define XCAST(fun) (typeof(ddi7avt.fn##fun))
254 # define XCAST(fun) (void*)
257 static ICOM_VTABLE(IDirectInput7A) ddi7avt = {
258 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
259 XCAST(QueryInterface)IDirectInputAImpl_QueryInterface,
260 XCAST(AddRef)IDirectInputAImpl_AddRef,
261 XCAST(Release)IDirectInputAImpl_Release,
262 XCAST(CreateDevice)IDirectInputAImpl_CreateDevice,
263 XCAST(EnumDevices)IDirectInputAImpl_EnumDevices,
264 XCAST(GetDeviceStatus)IDirectInputAImpl_GetDeviceStatus,
265 XCAST(RunControlPanel)IDirectInputAImpl_RunControlPanel,
266 XCAST(Initialize)IDirectInputAImpl_Initialize,
267 XCAST(FindDevice)IDirectInput2AImpl_FindDevice,
268 IDirectInput7AImpl_CreateDeviceEx
272 /***********************************************************************
273 * DllCanUnloadNow (DINPUT.@)
275 HRESULT WINAPI DINPUT_DllCanUnloadNow(void)
277 FIXME("(void): stub\n");
282 /***********************************************************************
283 * DllGetClassObject (DINPUT.@)
285 HRESULT WINAPI DINPUT_DllGetClassObject(REFCLSID rclsid, REFIID riid,
288 FIXME("(%p, %p, %p): stub\n", debugstr_guid(rclsid),
289 debugstr_guid(riid), ppv);
291 return CLASS_E_CLASSNOTAVAILABLE;
294 /***********************************************************************
295 * DllRegisterServer (DINPUT.@)
297 HRESULT WINAPI DINPUT_DllRegisterServer(void)
299 FIXME("(void): stub\n");
304 /***********************************************************************
305 * DllUnregisterServer (DINPUT.@)
307 HRESULT WINAPI DINPUT_DllUnregisterServer(void)
309 FIXME("(void): stub\n");