3 * Copyright 1998 Marcus Meissner
4 * Copyright 1998,1999 Lionel Ulmer
5 * Copyright 2000-2002 TransGaming Technologies Inc.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 * - Tomb Raider 2 Demo:
25 * Playable using keyboard only.
26 * - WingCommander Prophecy Demo:
27 * Doesn't get Input Focus.
29 * - Fallout : works great in X and DGA mode
39 #include "wine/debug.h"
40 #include "wine/unicode.h"
45 #include "dinput_private.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(dinput);
49 static IDirectInput7AVtbl ddi7avt;
50 static IDirectInput7WVtbl ddi7wvt;
51 static IDirectInput8AVtbl ddi8avt;
52 static IDirectInput8WVtbl ddi8wvt;
54 static const struct dinput_device *dinput_devices[] =
58 &joystick_linuxinput_device,
59 &joystick_linux_device
61 #define NB_DINPUT_DEVICES (sizeof(dinput_devices)/sizeof(dinput_devices[0]))
63 HINSTANCE DINPUT_instance = NULL;
65 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserv)
69 case DLL_PROCESS_ATTACH:
70 DisableThreadLibraryCalls(inst);
71 DINPUT_instance = inst;
73 case DLL_PROCESS_DETACH:
80 /******************************************************************************
81 * DirectInputCreateEx (DINPUT.@)
83 HRESULT WINAPI DirectInputCreateEx(
84 HINSTANCE hinst, DWORD dwVersion, REFIID riid, LPVOID *ppDI,
87 IDirectInputImpl* This;
89 TRACE("(0x%08lx,%04lx,%s,%p,%p)\n", (DWORD)hinst,dwVersion,debugstr_guid(riid),ppDI,punkOuter);
91 if (IsEqualGUID(&IID_IDirectInputA,riid) ||
92 IsEqualGUID(&IID_IDirectInput2A,riid) ||
93 IsEqualGUID(&IID_IDirectInput7A,riid)) {
94 This = HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl));
95 This->lpVtbl = &ddi7avt;
103 if (IsEqualGUID(&IID_IDirectInputW,riid) ||
104 IsEqualGUID(&IID_IDirectInput2W,riid) ||
105 IsEqualGUID(&IID_IDirectInput7W,riid)) {
106 This = HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl));
107 This->lpVtbl = &ddi7wvt;
115 if (IsEqualGUID(&IID_IDirectInput8A,riid)) {
116 This = HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl));
117 This->lpVtbl = &ddi8avt;
125 if (IsEqualGUID(&IID_IDirectInput8W,riid)) {
126 This = HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl));
127 This->lpVtbl = &ddi8wvt;
135 return DIERR_OLDDIRECTINPUTVERSION;
138 /******************************************************************************
139 * DirectInputCreateA (DINPUT.@)
141 HRESULT WINAPI DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTA *ppDI, LPUNKNOWN punkOuter)
143 IDirectInputImpl* This;
144 TRACE("(0x%08lx,%04lx,%p,%p)\n", (DWORD)hinst,dwVersion,ppDI,punkOuter);
145 This = HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl));
146 This->lpVtbl = &ddi7avt;
148 if (dwVersion >= 0x0800) {
151 /* We do not differientiate between version 1, 2 and 7 */
154 *ppDI = (IDirectInputA*)This;
159 /******************************************************************************
160 * DirectInputCreateW (DINPUT.@)
162 HRESULT WINAPI DirectInputCreateW(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTW *ppDI, LPUNKNOWN punkOuter)
164 IDirectInputImpl* This;
165 TRACE("(0x%08lx,%04lx,%p,%p)\n", (DWORD)hinst,dwVersion,ppDI,punkOuter);
166 This = HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl));
167 This->lpVtbl = &ddi7wvt;
169 if (dwVersion >= 0x0800) {
172 /* We do not differientiate between version 1, 2 and 7 */
175 *ppDI = (IDirectInputW*)This;
179 static const char *_dump_DIDEVTYPE_value(DWORD dwDevType) {
181 case 0: return "All devices";
182 case DIDEVTYPE_MOUSE: return "DIDEVTYPE_MOUSE";
183 case DIDEVTYPE_KEYBOARD: return "DIDEVTYPE_KEYBOARD";
184 case DIDEVTYPE_JOYSTICK: return "DIDEVTYPE_JOYSTICK";
185 case DIDEVTYPE_DEVICE: return "DIDEVTYPE_DEVICE";
186 default: return "Unkown";
190 static void _dump_EnumDevices_dwFlags(DWORD dwFlags) {
191 if (TRACE_ON(dinput)) {
193 static const struct {
197 #define FE(x) { x, #x}
198 FE(DIEDFL_ALLDEVICES),
199 FE(DIEDFL_ATTACHEDONLY),
200 FE(DIEDFL_FORCEFEEDBACK),
201 FE(DIEDFL_INCLUDEALIASES),
202 FE(DIEDFL_INCLUDEPHANTOMS)
206 DPRINTF("DIEDFL_ALLDEVICES");
209 for (i = 0; i < (sizeof(flags) / sizeof(flags[0])); i++)
210 if (flags[i].mask & dwFlags)
211 DPRINTF("%s ",flags[i].name);
215 /******************************************************************************
216 * IDirectInputA_EnumDevices
218 static HRESULT WINAPI IDirectInputAImpl_EnumDevices(
219 LPDIRECTINPUT7A iface, DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback,
220 LPVOID pvRef, DWORD dwFlags)
222 IDirectInputImpl *This = (IDirectInputImpl *)iface;
223 DIDEVICEINSTANCEA devInstance;
226 TRACE("(this=%p,0x%04lx '%s',%p,%p,%04lx)\n",
227 This, dwDevType, _dump_DIDEVTYPE_value(dwDevType),
228 lpCallback, pvRef, dwFlags);
229 TRACE(" flags: "); _dump_EnumDevices_dwFlags(dwFlags); TRACE("\n");
231 for (i = 0; i < NB_DINPUT_DEVICES; i++) {
232 if (!dinput_devices[i]->enum_deviceA) continue;
233 for (j = 0, r = -1; r != 0; j++) {
234 devInstance.dwSize = sizeof(devInstance);
235 TRACE(" - checking device %d ('%s')\n", i, dinput_devices[i]->name);
236 if ((r = dinput_devices[i]->enum_deviceA(dwDevType, dwFlags, &devInstance, This->version, j))) {
237 if (lpCallback(&devInstance,pvRef) == DIENUM_STOP)
245 /******************************************************************************
246 * IDirectInputW_EnumDevices
248 static HRESULT WINAPI IDirectInputWImpl_EnumDevices(
249 LPDIRECTINPUT7W iface, DWORD dwDevType, LPDIENUMDEVICESCALLBACKW lpCallback,
250 LPVOID pvRef, DWORD dwFlags)
252 IDirectInputImpl *This = (IDirectInputImpl *)iface;
253 DIDEVICEINSTANCEW devInstance;
256 TRACE("(this=%p,0x%04lx '%s',%p,%p,%04lx)\n",
257 This, dwDevType, _dump_DIDEVTYPE_value(dwDevType),
258 lpCallback, pvRef, dwFlags);
259 TRACE(" flags: "); _dump_EnumDevices_dwFlags(dwFlags); TRACE("\n");
261 for (i = 0; i < NB_DINPUT_DEVICES; i++) {
262 if (!dinput_devices[i]->enum_deviceW) continue;
263 for (j = 0, r = -1; r != 0; j++) {
264 devInstance.dwSize = sizeof(devInstance);
265 TRACE(" - checking device %d ('%s')\n", i, dinput_devices[i]->name);
266 if ((r = dinput_devices[i]->enum_deviceW(dwDevType, dwFlags, &devInstance, This->version, j))) {
267 if (lpCallback(&devInstance,pvRef) == DIENUM_STOP)
276 static ULONG WINAPI IDirectInputAImpl_AddRef(LPDIRECTINPUT7A iface)
278 IDirectInputImpl *This = (IDirectInputImpl *)iface;
279 return InterlockedIncrement((&This->ref));
282 static ULONG WINAPI IDirectInputAImpl_Release(LPDIRECTINPUT7A iface)
284 IDirectInputImpl *This = (IDirectInputImpl *)iface;
286 ref = InterlockedDecrement(&(This->ref));
288 HeapFree(GetProcessHeap(),0,This);
292 static HRESULT WINAPI IDirectInputAImpl_QueryInterface(LPDIRECTINPUT7A iface, REFIID riid, LPVOID *ppobj) {
293 IDirectInputImpl *This = (IDirectInputImpl *)iface;
295 TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
296 if (IsEqualGUID(&IID_IUnknown,riid) ||
297 IsEqualGUID(&IID_IDirectInputA,riid) ||
298 IsEqualGUID(&IID_IDirectInput2A,riid) ||
299 IsEqualGUID(&IID_IDirectInput7A,riid)) {
300 IDirectInputAImpl_AddRef(iface);
304 TRACE("Unsupported interface !\n");
308 static HRESULT WINAPI IDirectInputWImpl_QueryInterface(LPDIRECTINPUT7W iface, REFIID riid, LPVOID *ppobj) {
309 IDirectInputImpl *This = (IDirectInputImpl *)iface;
311 TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
312 if (IsEqualGUID(&IID_IUnknown,riid) ||
313 IsEqualGUID(&IID_IDirectInputW,riid) ||
314 IsEqualGUID(&IID_IDirectInput2W,riid) ||
315 IsEqualGUID(&IID_IDirectInput7W,riid)) {
316 IDirectInputAImpl_AddRef((LPDIRECTINPUT7A) iface);
320 TRACE("Unsupported interface !\n");
324 static HRESULT WINAPI IDirectInputAImpl_CreateDevice(
325 LPDIRECTINPUT7A iface,REFGUID rguid,LPDIRECTINPUTDEVICEA* pdev,
328 IDirectInputImpl *This = (IDirectInputImpl *)iface;
329 HRESULT ret_value = DIERR_DEVICENOTREG;
332 TRACE("(this=%p,%s,%p,%p)\n",This,debugstr_guid(rguid),pdev,punk);
335 WARN("invalid pointer: pdev == NULL\n");
340 WARN("invalid pointer: rguid == NULL\n");
344 /* Loop on all the devices to see if anyone matches the given GUID */
345 for (i = 0; i < NB_DINPUT_DEVICES; i++) {
347 if (!dinput_devices[i]->create_deviceA) continue;
348 if ((ret = dinput_devices[i]->create_deviceA(This, rguid, NULL, pdev)) == DI_OK)
351 if (ret == DIERR_NOINTERFACE)
352 ret_value = DIERR_NOINTERFACE;
358 static HRESULT WINAPI IDirectInputWImpl_CreateDevice(LPDIRECTINPUT7A iface,
359 REFGUID rguid, LPDIRECTINPUTDEVICEW* pdev, LPUNKNOWN punk) {
360 IDirectInputImpl *This = (IDirectInputImpl *)iface;
361 HRESULT ret_value = DIERR_DEVICENOTREG;
364 TRACE("(this=%p,%s,%p,%p)\n",This,debugstr_guid(rguid),pdev,punk);
366 /* Loop on all the devices to see if anyone matches the given GUID */
367 for (i = 0; i < NB_DINPUT_DEVICES; i++) {
369 if (!dinput_devices[i]->create_deviceW) continue;
370 if ((ret = dinput_devices[i]->create_deviceW(This, rguid, NULL, pdev)) == DI_OK)
373 if (ret == DIERR_NOINTERFACE)
374 ret_value = DIERR_NOINTERFACE;
380 static HRESULT WINAPI IDirectInputAImpl_Initialize(LPDIRECTINPUT7A iface, HINSTANCE hinst, DWORD x) {
381 return DIERR_ALREADYINITIALIZED;
384 static HRESULT WINAPI IDirectInputAImpl_GetDeviceStatus(LPDIRECTINPUT7A iface,
386 IDirectInputImpl *This = (IDirectInputImpl *)iface;
388 FIXME("(%p)->(%s): stub\n",This,debugstr_guid(rguid));
393 static HRESULT WINAPI IDirectInputAImpl_RunControlPanel(LPDIRECTINPUT7A iface,
396 IDirectInputImpl *This = (IDirectInputImpl *)iface;
397 FIXME("(%p)->(%08lx,%08lx): stub\n",This, (DWORD) hwndOwner, dwFlags);
402 static HRESULT WINAPI IDirectInput2AImpl_FindDevice(LPDIRECTINPUT7A iface, REFGUID rguid,
403 LPCSTR pszName, LPGUID pguidInstance) {
404 IDirectInputImpl *This = (IDirectInputImpl *)iface;
405 FIXME("(%p)->(%s, %s, %p): stub\n", This, debugstr_guid(rguid), pszName, pguidInstance);
410 static HRESULT WINAPI IDirectInput2WImpl_FindDevice(LPDIRECTINPUT7W iface, REFGUID rguid,
411 LPCWSTR pszName, LPGUID pguidInstance) {
412 IDirectInputImpl *This = (IDirectInputImpl *)iface;
413 FIXME("(%p)->(%s, %s, %p): stub\n", This, debugstr_guid(rguid), debugstr_w(pszName), pguidInstance);
418 static HRESULT WINAPI IDirectInput7AImpl_CreateDeviceEx(LPDIRECTINPUT7A iface, REFGUID rguid,
419 REFIID riid, LPVOID* pvOut, LPUNKNOWN lpUnknownOuter)
421 IDirectInputImpl *This = (IDirectInputImpl *)iface;
422 HRESULT ret_value = DIERR_DEVICENOTREG;
425 TRACE("(%p)->(%s, %s, %p, %p)\n", This, debugstr_guid(rguid), debugstr_guid(riid), pvOut, lpUnknownOuter);
427 /* Loop on all the devices to see if anyone matches the given GUID */
428 for (i = 0; i < NB_DINPUT_DEVICES; i++) {
430 if (!dinput_devices[i]->create_deviceA) continue;
431 if ((ret = dinput_devices[i]->create_deviceA(This, rguid, riid, (LPDIRECTINPUTDEVICEA*) pvOut)) == DI_OK)
434 if (ret == DIERR_NOINTERFACE)
435 ret_value = DIERR_NOINTERFACE;
441 static HRESULT WINAPI IDirectInput7WImpl_CreateDeviceEx(LPDIRECTINPUT7W iface, REFGUID rguid,
442 REFIID riid, LPVOID* pvOut, LPUNKNOWN lpUnknownOuter)
444 IDirectInputImpl *This = (IDirectInputImpl *)iface;
445 HRESULT ret_value = DIERR_DEVICENOTREG;
448 TRACE("(%p)->(%s, %s, %p, %p)\n", This, debugstr_guid(rguid), debugstr_guid(riid), pvOut, lpUnknownOuter);
450 /* Loop on all the devices to see if anyone matches the given GUID */
451 for (i = 0; i < NB_DINPUT_DEVICES; i++) {
453 if (!dinput_devices[i]->create_deviceW) continue;
454 if ((ret = dinput_devices[i]->create_deviceW(This, rguid, riid, (LPDIRECTINPUTDEVICEW*) pvOut)) == DI_OK)
457 if (ret == DIERR_NOINTERFACE)
458 ret_value = DIERR_NOINTERFACE;
464 static HRESULT WINAPI IDirectInput8AImpl_QueryInterface(LPDIRECTINPUT8A iface, REFIID riid, LPVOID *ppobj) {
465 IDirectInputImpl *This = (IDirectInputImpl *)iface;
467 TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
468 if (IsEqualGUID(&IID_IUnknown,riid) ||
469 IsEqualGUID(&IID_IDirectInput8A,riid)) {
470 IDirectInputAImpl_AddRef((LPDIRECTINPUT7A) iface);
474 TRACE("Unsupported interface !\n");
475 return E_NOINTERFACE;
478 static HRESULT WINAPI IDirectInput8WImpl_QueryInterface(LPDIRECTINPUT8W iface, REFIID riid, LPVOID *ppobj) {
479 IDirectInputImpl *This = (IDirectInputImpl *)iface;
481 TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
482 if (IsEqualGUID(&IID_IUnknown,riid) ||
483 IsEqualGUID(&IID_IDirectInput8W,riid)) {
484 IDirectInputAImpl_AddRef((LPDIRECTINPUT7A) iface);
488 TRACE("Unsupported interface !\n");
489 return E_NOINTERFACE;
492 static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics(
493 LPDIRECTINPUT8A iface, LPCSTR ptszUserName, LPDIACTIONFORMATA lpdiActionFormat,
494 LPDIENUMDEVICESBYSEMANTICSCBA lpCallback,
495 LPVOID pvRef, DWORD dwFlags
498 IDirectInputImpl *This = (IDirectInputImpl *)iface;
500 FIXME("(this=%p,%s,%p,%p,%p,%04lx): stub\n", This, ptszUserName, lpdiActionFormat,
501 lpCallback, pvRef, dwFlags);
505 static HRESULT WINAPI IDirectInput8WImpl_EnumDevicesBySemantics(
506 LPDIRECTINPUT8W iface, LPCWSTR ptszUserName, LPDIACTIONFORMATW lpdiActionFormat,
507 LPDIENUMDEVICESBYSEMANTICSCBW lpCallback,
508 LPVOID pvRef, DWORD dwFlags
511 IDirectInputImpl *This = (IDirectInputImpl *)iface;
513 FIXME("(this=%p,%s,%p,%p,%p,%04lx): stub\n", This, debugstr_w(ptszUserName), lpdiActionFormat,
514 lpCallback, pvRef, dwFlags);
518 static HRESULT WINAPI IDirectInput8AImpl_ConfigureDevices(
519 LPDIRECTINPUT8A iface, LPDICONFIGUREDEVICESCALLBACK lpdiCallback,
520 LPDICONFIGUREDEVICESPARAMSA lpdiCDParams, DWORD dwFlags, LPVOID pvRefData
523 IDirectInputImpl *This = (IDirectInputImpl *)iface;
525 FIXME("(this=%p,%p,%p,%04lx,%p): stub\n", This, lpdiCallback, lpdiCDParams,
530 static HRESULT WINAPI IDirectInput8WImpl_ConfigureDevices(
531 LPDIRECTINPUT8W iface, LPDICONFIGUREDEVICESCALLBACK lpdiCallback,
532 LPDICONFIGUREDEVICESPARAMSW lpdiCDParams, DWORD dwFlags, LPVOID pvRefData
535 IDirectInputImpl *This = (IDirectInputImpl *)iface;
537 FIXME("(this=%p,%p,%p,%04lx,%p): stub\n", This, lpdiCallback, lpdiCDParams,
542 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
543 # define XCAST(fun) (typeof(ddi7avt.fun))
545 # define XCAST(fun) (void*)
548 static IDirectInput7AVtbl ddi7avt = {
549 XCAST(QueryInterface)IDirectInputAImpl_QueryInterface,
550 XCAST(AddRef)IDirectInputAImpl_AddRef,
551 XCAST(Release)IDirectInputAImpl_Release,
552 XCAST(CreateDevice)IDirectInputAImpl_CreateDevice,
553 XCAST(EnumDevices)IDirectInputAImpl_EnumDevices,
554 XCAST(GetDeviceStatus)IDirectInputAImpl_GetDeviceStatus,
555 XCAST(RunControlPanel)IDirectInputAImpl_RunControlPanel,
556 XCAST(Initialize)IDirectInputAImpl_Initialize,
557 XCAST(FindDevice)IDirectInput2AImpl_FindDevice,
558 XCAST(CreateDeviceEx)IDirectInput7AImpl_CreateDeviceEx
562 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
563 # define XCAST(fun) (typeof(ddi7wvt.fun))
565 # define XCAST(fun) (void*)
568 static IDirectInput7WVtbl ddi7wvt = {
569 XCAST(QueryInterface)IDirectInputWImpl_QueryInterface,
570 XCAST(AddRef)IDirectInputAImpl_AddRef,
571 XCAST(Release)IDirectInputAImpl_Release,
572 XCAST(CreateDevice)IDirectInputWImpl_CreateDevice,
573 XCAST(EnumDevices)IDirectInputWImpl_EnumDevices,
574 XCAST(GetDeviceStatus)IDirectInputAImpl_GetDeviceStatus,
575 XCAST(RunControlPanel)IDirectInputAImpl_RunControlPanel,
576 XCAST(Initialize)IDirectInputAImpl_Initialize,
577 XCAST(FindDevice)IDirectInput2WImpl_FindDevice,
578 XCAST(CreateDeviceEx)IDirectInput7WImpl_CreateDeviceEx
582 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
583 # define XCAST(fun) (typeof(ddi8avt.fun))
585 # define XCAST(fun) (void*)
588 static IDirectInput8AVtbl ddi8avt = {
589 XCAST(QueryInterface)IDirectInput8AImpl_QueryInterface,
590 XCAST(AddRef)IDirectInputAImpl_AddRef,
591 XCAST(Release)IDirectInputAImpl_Release,
592 XCAST(CreateDevice)IDirectInputAImpl_CreateDevice,
593 XCAST(EnumDevices)IDirectInputAImpl_EnumDevices,
594 XCAST(GetDeviceStatus)IDirectInputAImpl_GetDeviceStatus,
595 XCAST(RunControlPanel)IDirectInputAImpl_RunControlPanel,
596 XCAST(Initialize)IDirectInputAImpl_Initialize,
597 XCAST(FindDevice)IDirectInput2AImpl_FindDevice,
598 XCAST(EnumDevicesBySemantics)IDirectInput8AImpl_EnumDevicesBySemantics,
599 XCAST(ConfigureDevices)IDirectInput8AImpl_ConfigureDevices
603 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
604 # define XCAST(fun) (typeof(ddi8wvt.fun))
606 # define XCAST(fun) (void*)
608 static IDirectInput8WVtbl ddi8wvt = {
609 XCAST(QueryInterface)IDirectInput8WImpl_QueryInterface,
610 XCAST(AddRef)IDirectInputAImpl_AddRef,
611 XCAST(Release)IDirectInputAImpl_Release,
612 XCAST(CreateDevice)IDirectInputWImpl_CreateDevice,
613 XCAST(EnumDevices)IDirectInputWImpl_EnumDevices,
614 XCAST(GetDeviceStatus)IDirectInputAImpl_GetDeviceStatus,
615 XCAST(RunControlPanel)IDirectInputAImpl_RunControlPanel,
616 XCAST(Initialize)IDirectInputAImpl_Initialize,
617 XCAST(FindDevice)IDirectInput2WImpl_FindDevice,
618 XCAST(EnumDevicesBySemantics)IDirectInput8WImpl_EnumDevicesBySemantics,
619 XCAST(ConfigureDevices)IDirectInput8WImpl_ConfigureDevices
623 /*******************************************************************************
624 * DirectInput ClassFactory
628 /* IUnknown fields */
629 IClassFactoryVtbl *lpVtbl;
633 static HRESULT WINAPI DICF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
634 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
636 FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
637 return E_NOINTERFACE;
640 static ULONG WINAPI DICF_AddRef(LPCLASSFACTORY iface) {
641 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
642 return InterlockedIncrement(&(This->ref));
645 static ULONG WINAPI DICF_Release(LPCLASSFACTORY iface) {
646 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
647 /* static class, won't be freed */
648 return InterlockedDecrement(&(This->ref));
651 static HRESULT WINAPI DICF_CreateInstance(
652 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
654 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
656 TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
657 if ( IsEqualGUID( &IID_IDirectInputA, riid ) ||
658 IsEqualGUID( &IID_IDirectInputW, riid ) ||
659 IsEqualGUID( &IID_IDirectInput2A, riid ) ||
660 IsEqualGUID( &IID_IDirectInput2W, riid ) ||
661 IsEqualGUID( &IID_IDirectInput7A, riid ) ||
662 IsEqualGUID( &IID_IDirectInput7W, riid ) ||
663 IsEqualGUID( &IID_IDirectInput8A, riid ) ||
664 IsEqualGUID( &IID_IDirectInput8W, riid ) ) {
665 /* FIXME: reuse already created dinput if present? */
666 return DirectInputCreateEx(0,0,riid,ppobj,pOuter);
669 FIXME("(%p,%p,%s,%p) Interface not found!\n",This,pOuter,debugstr_guid(riid),ppobj);
670 return E_NOINTERFACE;
673 static HRESULT WINAPI DICF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
674 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
675 FIXME("(%p)->(%d),stub!\n",This,dolock);
679 static IClassFactoryVtbl DICF_Vtbl = {
686 static IClassFactoryImpl DINPUT_CF = {&DICF_Vtbl, 1 };
688 /***********************************************************************
689 * DllCanUnloadNow (DINPUT.@)
691 HRESULT WINAPI DINPUT_DllCanUnloadNow(void)
693 FIXME("(void): stub\n");
698 /***********************************************************************
699 * DllGetClassObject (DINPUT.@)
701 HRESULT WINAPI DINPUT_DllGetClassObject(REFCLSID rclsid, REFIID riid,
704 TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
705 if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) {
706 *ppv = (LPVOID)&DINPUT_CF;
707 IClassFactory_AddRef((IClassFactory*)*ppv);
711 FIXME("(%s,%s,%p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
712 return CLASS_E_CLASSNOTAVAILABLE;