-/* DirectInput\r
- *\r
- * Copyright 1998 Marcus Meissner\r
- * Copyright 1998,1999 Lionel Ulmer\r
- * Copyright 2000-2002 TransGaming Technologies Inc.\r
- *\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
- */\r
-/* Status:\r
- *\r
- * - Tomb Raider 2 Demo:\r
- * Playable using keyboard only.\r
- * - WingCommander Prophecy Demo:\r
- * Doesn't get Input Focus.\r
- *\r
- * - Fallout : works great in X and DGA mode\r
- */\r
-\r
-#include "config.h"\r
-#include "wine/port.h"\r
-\r
-#include <assert.h>\r
-#include <stdarg.h>\r
-#include <string.h>\r
-\r
-#define COBJMACROS\r
-\r
-#include "wine/debug.h"\r
-#include "wine/unicode.h"\r
-#include "windef.h"\r
-#include "winbase.h"\r
-#include "winuser.h"\r
-#include "winerror.h"\r
-#include "dinput_private.h"\r
-\r
-WINE_DEFAULT_DEBUG_CHANNEL(dinput);\r
-\r
-static IDirectInput7AVtbl ddi7avt;\r
-static IDirectInput7WVtbl ddi7wvt;\r
-static IDirectInput8AVtbl ddi8avt;\r
-static IDirectInput8WVtbl ddi8wvt;\r
-\r
-/* This array will be filled a dinput.so loading */\r
-#define MAX_WINE_DINPUT_DEVICES 4\r
-static dinput_device * dinput_devices[MAX_WINE_DINPUT_DEVICES];\r
-static int nrof_dinput_devices = 0;\r
-\r
-HINSTANCE DINPUT_instance = NULL;\r
-\r
-BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserv)\r
-{\r
- switch(reason)\r
- {\r
- case DLL_PROCESS_ATTACH:\r
- DisableThreadLibraryCalls(inst);\r
- DINPUT_instance = inst;\r
- break;\r
- case DLL_PROCESS_DETACH:\r
- break;\r
- }\r
- return TRUE;\r
-}\r
-\r
-/* register a direct draw driver. We better not use malloc for we are in\r
- * the ELF startup initialisation at this point.\r
- */\r
-void dinput_register_device(dinput_device *device) {\r
- int i;\r
-\r
- /* insert according to priority */\r
- for (i=0;i<nrof_dinput_devices;i++) {\r
- if (dinput_devices[i]->pref <= device->pref) {\r
- memcpy(dinput_devices+i+1,dinput_devices+i,sizeof(dinput_devices[0])*(nrof_dinput_devices-i));\r
- dinput_devices[i] = device;\r
- break;\r
- }\r
- }\r
- if (i==nrof_dinput_devices) /* not found, or too low priority */\r
- dinput_devices[nrof_dinput_devices] = device;\r
-\r
- nrof_dinput_devices++;\r
-\r
- /* increase MAX_DDRAW_DRIVERS if the line below triggers */\r
- assert(nrof_dinput_devices <= MAX_WINE_DINPUT_DEVICES);\r
-}\r
-\r
-/******************************************************************************\r
- * DirectInputCreateEx (DINPUT.@)\r
- */\r
-HRESULT WINAPI DirectInputCreateEx(\r
- HINSTANCE hinst, DWORD dwVersion, REFIID riid, LPVOID *ppDI,\r
- LPUNKNOWN punkOuter) \r
-{\r
- IDirectInputImpl* This;\r
-\r
- TRACE("(0x%08lx,%04lx,%s,%p,%p)\n", (DWORD)hinst,dwVersion,debugstr_guid(riid),ppDI,punkOuter);\r
-\r
- if (IsEqualGUID(&IID_IDirectInputA,riid) ||\r
- IsEqualGUID(&IID_IDirectInput2A,riid) ||\r
- IsEqualGUID(&IID_IDirectInput7A,riid)) {\r
- This = (IDirectInputImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl));\r
- This->lpVtbl = &ddi7avt;\r
- This->ref = 1;\r
- This->version = 1;\r
- *ppDI = This;\r
-\r
- return DI_OK;\r
- }\r
-\r
- if (IsEqualGUID(&IID_IDirectInputW,riid) ||\r
- IsEqualGUID(&IID_IDirectInput2W,riid) ||\r
- IsEqualGUID(&IID_IDirectInput7W,riid)) {\r
- This = (IDirectInputImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl));\r
- This->lpVtbl = &ddi7wvt;\r
- This->ref = 1;\r
- This->version = 1;\r
- *ppDI = This;\r
-\r
- return DI_OK;\r
- }\r
-\r
- if (IsEqualGUID(&IID_IDirectInput8A,riid)) {\r
- This = (IDirectInputImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl));\r
- This->lpVtbl = &ddi8avt;\r
- This->ref = 1;\r
- This->version = 8;\r
- *ppDI = This;\r
-\r
- return DI_OK;\r
- }\r
-\r
- if (IsEqualGUID(&IID_IDirectInput8W,riid)) {\r
- This = (IDirectInputImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl));\r
- This->lpVtbl = &ddi8wvt;\r
- This->ref = 1;\r
- This->version = 8;\r
- *ppDI = This;\r
-\r
- return DI_OK;\r
- }\r
-\r
- return DIERR_OLDDIRECTINPUTVERSION;\r
-}\r
-\r
-/******************************************************************************\r
- * DirectInputCreateA (DINPUT.@)\r
- */\r
-HRESULT WINAPI DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTA *ppDI, LPUNKNOWN punkOuter)\r
-{\r
- IDirectInputImpl* This;\r
- TRACE("(0x%08lx,%04lx,%p,%p)\n", (DWORD)hinst,dwVersion,ppDI,punkOuter);\r
-\r
- //trace:dinput:DirectInputCreateA (0x00400000,0500,0x42bafc54,(nil))\r
- This = (IDirectInputImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl));\r
- This->lpVtbl = &ddi7avt;\r
- This->ref = 1;\r
- if (dwVersion > 0x0700) {\r
- This->version = 8;\r
- } else {\r
- /* We do not differientiate between version 1, 2 and 7 */\r
- This->version = 1;\r
- }\r
- *ppDI = (IDirectInputA*)This;\r
- return 0;\r
-\r
-}\r
-\r
-/******************************************************************************\r
- * DirectInputCreateW (DINPUT.@)\r
- */\r
-HRESULT WINAPI DirectInputCreateW(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTW *ppDI, LPUNKNOWN punkOuter)\r
-{\r
- IDirectInputImpl* This;\r
- TRACE("(0x%08lx,%04lx,%p,%p)\n", (DWORD)hinst,dwVersion,ppDI,punkOuter);\r
- This = (IDirectInputImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl));\r
- This->lpVtbl = &ddi7wvt;\r
- This->ref = 1;\r
- if (dwVersion >= 0x0800) {\r
- This->version = 8;\r
- } else {\r
- /* We do not differientiate between version 1, 2 and 7 */\r
- This->version = 1;\r
- }\r
- *ppDI = (IDirectInputW*)This;\r
- return 0;\r
-}\r
-\r
-static const char *_dump_DIDEVTYPE_value(DWORD dwDevType) {\r
- switch (dwDevType) {\r
- case 0: return "All devices";\r
- case DIDEVTYPE_MOUSE: return "DIDEVTYPE_MOUSE";\r
- case DIDEVTYPE_KEYBOARD: return "DIDEVTYPE_KEYBOARD";\r
- case DIDEVTYPE_JOYSTICK: return "DIDEVTYPE_JOYSTICK";\r
- case DIDEVTYPE_DEVICE: return "DIDEVTYPE_DEVICE";\r
- default: return "Unkown";\r
- }\r
-}\r
-\r
-static void _dump_EnumDevices_dwFlags(DWORD dwFlags) {\r
- if (TRACE_ON(dinput)) {\r
- unsigned int i;\r
- static const struct {\r
- DWORD mask;\r
- const char *name;\r
- } flags[] = {\r
-#define FE(x) { x, #x}\r
- FE(DIEDFL_ALLDEVICES),\r
- FE(DIEDFL_ATTACHEDONLY),\r
- FE(DIEDFL_FORCEFEEDBACK),\r
- FE(DIEDFL_INCLUDEALIASES),\r
- FE(DIEDFL_INCLUDEPHANTOMS)\r
-#undef FE\r
- };\r
- if (dwFlags == 0) {\r
- DPRINTF("DIEDFL_ALLDEVICES");\r
- return;\r
- }\r
- for (i = 0; i < (sizeof(flags) / sizeof(flags[0])); i++)\r
- if (flags[i].mask & dwFlags)\r
- DPRINTF("%s ",flags[i].name);\r
- }\r
-}\r
-\r
-/******************************************************************************\r
- * IDirectInputA_EnumDevices\r
- */\r
-static HRESULT WINAPI IDirectInputAImpl_EnumDevices(\r
- LPDIRECTINPUT7A iface, DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback,\r
- LPVOID pvRef, DWORD dwFlags)\r
-{\r
- IDirectInputImpl *This = (IDirectInputImpl *)iface;\r
- DIDEVICEINSTANCEA devInstance;\r
- int i, j, r;\r
- \r
- TRACE("(this=%p,0x%04lx '%s',%p,%p,%04lx)\n",\r
- This, dwDevType, _dump_DIDEVTYPE_value(dwDevType),\r
- lpCallback, pvRef, dwFlags);\r
-\r
- if (nrof_dinput_devices==0){\r
- scan_mouse();\r
- scan_keyboard();\r
- }\r
- \r
- TRACE(" flags: "); _dump_EnumDevices_dwFlags(dwFlags); TRACE("\n");\r
- \r
-\r
- for (i = 0; i < nrof_dinput_devices; i++) {\r
- for (j = 0, r = -1; r != 0; j++) {\r
- devInstance.dwSize = sizeof(devInstance);\r
- TRACE(" - checking device %d ('%s')\n", i, dinput_devices[i]->name);\r
- \r
-\r
- if ((r = dinput_devices[i]->enum_deviceA(dwDevType, dwFlags, &devInstance, This->version, j))) {\r
- if (lpCallback(&devInstance,pvRef) == DIENUM_STOP)\r
- return 0;\r
- }\r
- }\r
- }\r
- \r
- return 0;\r
-}\r
-/******************************************************************************\r
- * IDirectInputW_EnumDevices\r
- */\r
-static HRESULT WINAPI IDirectInputWImpl_EnumDevices(\r
- LPDIRECTINPUT7W iface, DWORD dwDevType, LPDIENUMDEVICESCALLBACKW lpCallback,\r
- LPVOID pvRef, DWORD dwFlags) \r
-{\r
- IDirectInputImpl *This = (IDirectInputImpl *)iface;\r
- DIDEVICEINSTANCEW devInstance;\r
- int i, j, r;\r
- \r
- if (nrof_dinput_devices==0){\r
- scan_mouse();\r
- scan_keyboard();\r
- }\r
-\r
- TRACE("(this=%p,0x%04lx '%s',%p,%p,%04lx)\n",\r
- This, dwDevType, _dump_DIDEVTYPE_value(dwDevType),\r
- lpCallback, pvRef, dwFlags);\r
- TRACE(" flags: "); _dump_EnumDevices_dwFlags(dwFlags); TRACE("\n");\r
-\r
-\r
- for (i = 0; i < nrof_dinput_devices; i++) {\r
- for (j = 0, r = -1; r != 0; j++) {\r
- devInstance.dwSize = sizeof(devInstance);\r
- TRACE(" - checking device %d ('%s')\n", i, dinput_devices[i]->name);\r
- if ((r = dinput_devices[i]->enum_deviceW(dwDevType, dwFlags, &devInstance, This->version, j))) {\r
- if (lpCallback(&devInstance,pvRef) == DIENUM_STOP)\r
- return 0;\r
- }\r
- }\r
- }\r
- \r
- return 0;\r
-}\r
-\r
-static ULONG WINAPI IDirectInputAImpl_AddRef(LPDIRECTINPUT7A iface)\r
-{\r
- IDirectInputImpl *This = (IDirectInputImpl *)iface;\r
- return InterlockedIncrement((&This->ref));\r
-}\r
-\r
-static ULONG WINAPI IDirectInputAImpl_Release(LPDIRECTINPUT7A iface)\r
-{\r
- IDirectInputImpl *This = (IDirectInputImpl *)iface;\r
- ULONG ref;\r
- ref = InterlockedDecrement(&(This->ref));\r
- if (ref == 0)\r
- HeapFree(GetProcessHeap(),0,This);\r
- return ref;\r
-}\r
-\r
-static HRESULT WINAPI IDirectInputAImpl_QueryInterface(LPDIRECTINPUT7A iface, REFIID riid, LPVOID *ppobj) {\r
- IDirectInputImpl *This = (IDirectInputImpl *)iface;\r
-\r
- TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);\r
- if (IsEqualGUID(&IID_IUnknown,riid) ||\r
- IsEqualGUID(&IID_IDirectInputA,riid) ||\r
- IsEqualGUID(&IID_IDirectInput2A,riid) ||\r
- IsEqualGUID(&IID_IDirectInput7A,riid)) {\r
- IDirectInputAImpl_AddRef(iface);\r
- *ppobj = This;\r
- return 0;\r
- }\r
- TRACE("Unsupported interface !\n");\r
- return E_FAIL;\r
-}\r
-\r
-static HRESULT WINAPI IDirectInputWImpl_QueryInterface(LPDIRECTINPUT7W iface, REFIID riid, LPVOID *ppobj) {\r
- IDirectInputImpl *This = (IDirectInputImpl *)iface;\r
-\r
- TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);\r
- if (IsEqualGUID(&IID_IUnknown,riid) ||\r
- IsEqualGUID(&IID_IDirectInputW,riid) ||\r
- IsEqualGUID(&IID_IDirectInput2W,riid) ||\r
- IsEqualGUID(&IID_IDirectInput7W,riid)) {\r
- IDirectInputAImpl_AddRef((LPDIRECTINPUT7A) iface);\r
- *ppobj = This;\r
- return 0;\r
- }\r
- TRACE("Unsupported interface !\n");\r
- return E_FAIL;\r
-}\r
-\r
-static HRESULT WINAPI IDirectInputAImpl_CreateDevice(\r
- LPDIRECTINPUT7A iface,REFGUID rguid,LPDIRECTINPUTDEVICEA* pdev,\r
- LPUNKNOWN punk\r
-) {\r
- IDirectInputImpl *This = (IDirectInputImpl *)iface;\r
- HRESULT ret_value = DIERR_DEVICENOTREG;\r
- int i;\r
-\r
- TRACE("(this=%p,%s,%p,%p)\n",This,debugstr_guid(rguid),pdev,punk);\r
- \r
- if (nrof_dinput_devices==0){\r
- scan_mouse();\r
- scan_keyboard();\r
- }\r
- \r
- /* Loop on all the devices to see if anyone matches the given GUID */\r
- for (i = 0; i < nrof_dinput_devices; i++) {\r
- HRESULT ret;\r
- if ((ret = dinput_devices[i]->create_deviceA(This, rguid, NULL, pdev)) == DI_OK)\r
- return DI_OK;\r
-\r
- if (ret == DIERR_NOINTERFACE)\r
- ret_value = DIERR_NOINTERFACE;\r
- }\r
-\r
- return ret_value;\r
-}\r
-\r
-static HRESULT WINAPI IDirectInputWImpl_CreateDevice(LPDIRECTINPUT7A iface, \r
- REFGUID rguid, LPDIRECTINPUTDEVICEW* pdev, LPUNKNOWN punk) {\r
- IDirectInputImpl *This = (IDirectInputImpl *)iface;\r
- HRESULT ret_value = DIERR_DEVICENOTREG;\r
- int i;\r
- \r
- TRACE("(this=%p,%s,%p,%p)\n",This,debugstr_guid(rguid),pdev,punk);\r
-\r
- if (nrof_dinput_devices==0){\r
- scan_mouse();\r
- scan_keyboard();\r
- }\r
- \r
- /* Loop on all the devices to see if anyone matches the given GUID */\r
- for (i = 0; i < nrof_dinput_devices; i++) {\r
- HRESULT ret;\r
- if ((ret = dinput_devices[i]->create_deviceW(This, rguid, NULL, pdev)) == DI_OK)\r
- return DI_OK;\r
-\r
- if (ret == DIERR_NOINTERFACE)\r
- ret_value = DIERR_NOINTERFACE;\r
- }\r
-\r
- return ret_value;\r
-}\r
-\r
-static HRESULT WINAPI IDirectInputAImpl_Initialize(LPDIRECTINPUT7A iface, HINSTANCE hinst, DWORD x) {\r
- return DIERR_ALREADYINITIALIZED;\r
-}\r
-\r
-static HRESULT WINAPI IDirectInputAImpl_GetDeviceStatus(LPDIRECTINPUT7A iface,\r
- REFGUID rguid) {\r
- IDirectInputImpl *This = (IDirectInputImpl *)iface;\r
-\r
- FIXME("(%p)->(%s): stub\n",This,debugstr_guid(rguid));\r
-\r
- return DI_OK;\r
-}\r
-\r
-static HRESULT WINAPI IDirectInputAImpl_RunControlPanel(LPDIRECTINPUT7A iface,\r
- HWND hwndOwner,\r
- DWORD dwFlags) {\r
- IDirectInputImpl *This = (IDirectInputImpl *)iface;\r
- FIXME("(%p)->(%08lx,%08lx): stub\n",This, (DWORD) hwndOwner, dwFlags);\r
-\r
- return DI_OK;\r
-}\r
-\r
-static HRESULT WINAPI IDirectInput2AImpl_FindDevice(LPDIRECTINPUT7A iface, REFGUID rguid,\r
- LPCSTR pszName, LPGUID pguidInstance) {\r
- IDirectInputImpl *This = (IDirectInputImpl *)iface;\r
- FIXME("(%p)->(%s, %s, %p): stub\n", This, debugstr_guid(rguid), pszName, pguidInstance);\r
-\r
- return DI_OK;\r
-}\r
-\r
-static HRESULT WINAPI IDirectInput2WImpl_FindDevice(LPDIRECTINPUT7W iface, REFGUID rguid,\r
- LPCWSTR pszName, LPGUID pguidInstance) {\r
- IDirectInputImpl *This = (IDirectInputImpl *)iface;\r
- FIXME("(%p)->(%s, %s, %p): stub\n", This, debugstr_guid(rguid), debugstr_w(pszName), pguidInstance);\r
-\r
- return DI_OK;\r
-}\r
-\r
-static HRESULT WINAPI IDirectInput7AImpl_CreateDeviceEx(LPDIRECTINPUT7A iface, REFGUID rguid,\r
- REFIID riid, LPVOID* pvOut, LPUNKNOWN lpUnknownOuter)\r
-{\r
- IDirectInputImpl *This = (IDirectInputImpl *)iface;\r
- HRESULT ret_value = DIERR_DEVICENOTREG;\r
- int i;\r
-\r
- TRACE("(%p)->(%s, %s, %p, %p)\n", This, debugstr_guid(rguid), debugstr_guid(riid), pvOut, lpUnknownOuter);\r
-\r
- if (nrof_dinput_devices==0){\r
- scan_mouse();\r
- scan_keyboard();\r
- } \r
-\r
- /* Loop on all the devices to see if anyone matches the given GUID */\r
- for (i = 0; i < nrof_dinput_devices; i++) {\r
- HRESULT ret;\r
- if ((ret = dinput_devices[i]->create_deviceA(This, rguid, riid, (LPDIRECTINPUTDEVICEA*) pvOut)) == DI_OK)\r
- return DI_OK;\r
-\r
- if (ret == DIERR_NOINTERFACE)\r
- ret_value = DIERR_NOINTERFACE;\r
- }\r
-\r
- return ret_value;\r
-}\r
-\r
-static HRESULT WINAPI IDirectInput7WImpl_CreateDeviceEx(LPDIRECTINPUT7W iface, REFGUID rguid,\r
- REFIID riid, LPVOID* pvOut, LPUNKNOWN lpUnknownOuter)\r
-{\r
- IDirectInputImpl *This = (IDirectInputImpl *)iface;\r
- HRESULT ret_value = DIERR_DEVICENOTREG;\r
- int i;\r
-\r
- TRACE("(%p)->(%s, %s, %p, %p)\n", This, debugstr_guid(rguid), debugstr_guid(riid), pvOut, lpUnknownOuter);\r
-\r
- if (nrof_dinput_devices==0){\r
- scan_mouse();\r
- scan_keyboard();\r
- }\r
- \r
-\r
-\r
- /* Loop on all the devices to see if anyone matches the given GUID */\r
- for (i = 0; i < nrof_dinput_devices; i++) {\r
- HRESULT ret;\r
- if ((ret = dinput_devices[i]->create_deviceW(This, rguid, riid, (LPDIRECTINPUTDEVICEW*) pvOut)) == DI_OK)\r
- return DI_OK;\r
-\r
- if (ret == DIERR_NOINTERFACE)\r
- ret_value = DIERR_NOINTERFACE;\r
- }\r
-\r
- return ret_value;\r
-}\r
-\r
-static HRESULT WINAPI IDirectInput8AImpl_QueryInterface(LPDIRECTINPUT8A iface, REFIID riid, LPVOID *ppobj) {\r
- IDirectInputImpl *This = (IDirectInputImpl *)iface;\r
-\r
- TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);\r
- if (IsEqualGUID(&IID_IUnknown,riid) ||\r
- IsEqualGUID(&IID_IDirectInput8A,riid)) {\r
- IDirectInputAImpl_AddRef((LPDIRECTINPUT7A) iface);\r
- *ppobj = This;\r
- return 0;\r
- }\r
- TRACE("Unsupported interface !\n");\r
- return E_NOINTERFACE;\r
-}\r
-\r
-static HRESULT WINAPI IDirectInput8WImpl_QueryInterface(LPDIRECTINPUT8W iface, REFIID riid, LPVOID *ppobj) {\r
- IDirectInputImpl *This = (IDirectInputImpl *)iface;\r
-\r
- TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);\r
- if (IsEqualGUID(&IID_IUnknown,riid) ||\r
- IsEqualGUID(&IID_IDirectInput8W,riid)) {\r
- IDirectInputAImpl_AddRef((LPDIRECTINPUT7A) iface);\r
- *ppobj = This;\r
- return 0;\r
- }\r
- TRACE("Unsupported interface !\n");\r
- return E_NOINTERFACE;\r
-}\r
-\r
-static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics(\r
- LPDIRECTINPUT8A iface, LPCSTR ptszUserName, LPDIACTIONFORMATA lpdiActionFormat,\r
- LPDIENUMDEVICESBYSEMANTICSCBA lpCallback,\r
- LPVOID pvRef, DWORD dwFlags\r
-)\r
-{\r
- IDirectInputImpl *This = (IDirectInputImpl *)iface;\r
-\r
- FIXME("(this=%p,%s,%p,%p,%p,%04lx): stub\n", This, ptszUserName, lpdiActionFormat,\r
- lpCallback, pvRef, dwFlags);\r
- return 0;\r
-}\r
-\r
-static HRESULT WINAPI IDirectInput8WImpl_EnumDevicesBySemantics(\r
- LPDIRECTINPUT8W iface, LPCWSTR ptszUserName, LPDIACTIONFORMATW lpdiActionFormat,\r
- LPDIENUMDEVICESBYSEMANTICSCBW lpCallback,\r
- LPVOID pvRef, DWORD dwFlags\r
-)\r
-{\r
- IDirectInputImpl *This = (IDirectInputImpl *)iface;\r
-\r
- FIXME("(this=%p,%s,%p,%p,%p,%04lx): stub\n", This, debugstr_w(ptszUserName), lpdiActionFormat,\r
- lpCallback, pvRef, dwFlags);\r
- return 0;\r
-}\r
-\r
-static HRESULT WINAPI IDirectInput8AImpl_ConfigureDevices(\r
- LPDIRECTINPUT8A iface, LPDICONFIGUREDEVICESCALLBACK lpdiCallback,\r
- LPDICONFIGUREDEVICESPARAMSA lpdiCDParams, DWORD dwFlags, LPVOID pvRefData\r
-)\r
-{\r
- IDirectInputImpl *This = (IDirectInputImpl *)iface;\r
-\r
- FIXME("(this=%p,%p,%p,%04lx,%p): stub\n", This, lpdiCallback, lpdiCDParams,\r
- dwFlags, pvRefData);\r
- return 0;\r
-}\r
-\r
-static HRESULT WINAPI IDirectInput8WImpl_ConfigureDevices(\r
- LPDIRECTINPUT8W iface, LPDICONFIGUREDEVICESCALLBACK lpdiCallback,\r
- LPDICONFIGUREDEVICESPARAMSW lpdiCDParams, DWORD dwFlags, LPVOID pvRefData\r
-)\r
-{\r
- IDirectInputImpl *This = (IDirectInputImpl *)iface;\r
-\r
- FIXME("(this=%p,%p,%p,%04lx,%p): stub\n", This, lpdiCallback, lpdiCDParams,\r
- dwFlags, pvRefData);\r
- return 0;\r
-}\r
-\r
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)\r
-# define XCAST(fun) (typeof(ddi7avt.fun))\r
-#else\r
-# define XCAST(fun) (void*)\r
-#endif\r
-\r
-static IDirectInput7AVtbl ddi7avt = {\r
- XCAST(QueryInterface)IDirectInputAImpl_QueryInterface,\r
- XCAST(AddRef)IDirectInputAImpl_AddRef,\r
- XCAST(Release)IDirectInputAImpl_Release,\r
- XCAST(CreateDevice)IDirectInputAImpl_CreateDevice,\r
- XCAST(EnumDevices)IDirectInputAImpl_EnumDevices,\r
- XCAST(GetDeviceStatus)IDirectInputAImpl_GetDeviceStatus,\r
- XCAST(RunControlPanel)IDirectInputAImpl_RunControlPanel,\r
- XCAST(Initialize)IDirectInputAImpl_Initialize,\r
- XCAST(FindDevice)IDirectInput2AImpl_FindDevice,\r
- XCAST(CreateDeviceEx)IDirectInput7AImpl_CreateDeviceEx\r
-};\r
-\r
-#undef XCAST\r
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)\r
-# define XCAST(fun) (typeof(ddi7wvt.fun))\r
-#else\r
-# define XCAST(fun) (void*)\r
-#endif\r
-\r
-static IDirectInput7WVtbl ddi7wvt = {\r
- XCAST(QueryInterface)IDirectInputWImpl_QueryInterface,\r
- XCAST(AddRef)IDirectInputAImpl_AddRef,\r
- XCAST(Release)IDirectInputAImpl_Release,\r
- XCAST(CreateDevice)IDirectInputWImpl_CreateDevice,\r
- XCAST(EnumDevices)IDirectInputWImpl_EnumDevices,\r
- XCAST(GetDeviceStatus)IDirectInputAImpl_GetDeviceStatus,\r
- XCAST(RunControlPanel)IDirectInputAImpl_RunControlPanel,\r
- XCAST(Initialize)IDirectInputAImpl_Initialize,\r
- XCAST(FindDevice)IDirectInput2WImpl_FindDevice,\r
- XCAST(CreateDeviceEx)IDirectInput7WImpl_CreateDeviceEx\r
-};\r
-#undef XCAST\r
-\r
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)\r
-# define XCAST(fun) (typeof(ddi8avt.fun))\r
-#else\r
-# define XCAST(fun) (void*)\r
-#endif\r
-\r
-static IDirectInput8AVtbl ddi8avt = {\r
- XCAST(QueryInterface)IDirectInput8AImpl_QueryInterface,\r
- XCAST(AddRef)IDirectInputAImpl_AddRef,\r
- XCAST(Release)IDirectInputAImpl_Release,\r
- XCAST(CreateDevice)IDirectInputAImpl_CreateDevice,\r
- XCAST(EnumDevices)IDirectInputAImpl_EnumDevices,\r
- XCAST(GetDeviceStatus)IDirectInputAImpl_GetDeviceStatus,\r
- XCAST(RunControlPanel)IDirectInputAImpl_RunControlPanel,\r
- XCAST(Initialize)IDirectInputAImpl_Initialize,\r
- XCAST(FindDevice)IDirectInput2AImpl_FindDevice,\r
- XCAST(EnumDevicesBySemantics)IDirectInput8AImpl_EnumDevicesBySemantics,\r
- XCAST(ConfigureDevices)IDirectInput8AImpl_ConfigureDevices\r
-};\r
-#undef XCAST\r
-\r
-#if !defined(__STRICT_ANSI__) && defined(__GNUC__)\r
-# define XCAST(fun) (typeof(ddi8wvt.fun))\r
-#else\r
-# define XCAST(fun) (void*)\r
-#endif\r
-static IDirectInput8WVtbl ddi8wvt = {\r
- XCAST(QueryInterface)IDirectInput8WImpl_QueryInterface,\r
- XCAST(AddRef)IDirectInputAImpl_AddRef,\r
- XCAST(Release)IDirectInputAImpl_Release,\r
- XCAST(CreateDevice)IDirectInputWImpl_CreateDevice,\r
- XCAST(EnumDevices)IDirectInputWImpl_EnumDevices,\r
- XCAST(GetDeviceStatus)IDirectInputAImpl_GetDeviceStatus,\r
- XCAST(RunControlPanel)IDirectInputAImpl_RunControlPanel,\r
- XCAST(Initialize)IDirectInputAImpl_Initialize,\r
- XCAST(FindDevice)IDirectInput2WImpl_FindDevice,\r
- XCAST(EnumDevicesBySemantics)IDirectInput8WImpl_EnumDevicesBySemantics,\r
- XCAST(ConfigureDevices)IDirectInput8WImpl_ConfigureDevices\r
-};\r
-#undef XCAST\r
-\r
-/*******************************************************************************\r
- * DirectInput ClassFactory\r
- */\r
-typedef struct\r
-{\r
- /* IUnknown fields */\r
- IClassFactoryVtbl *lpVtbl;\r
- DWORD ref;\r
-} IClassFactoryImpl;\r
-\r
-static HRESULT WINAPI DICF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {\r
- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;\r
-\r
- FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);\r
- return E_NOINTERFACE;\r
-}\r
-\r
-static ULONG WINAPI DICF_AddRef(LPCLASSFACTORY iface) {\r
- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;\r
- return InterlockedIncrement(&(This->ref));\r
-}\r
-\r
-static ULONG WINAPI DICF_Release(LPCLASSFACTORY iface) {\r
- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;\r
- /* static class, won't be freed */\r
- return InterlockedDecrement(&(This->ref));\r
-}\r
-\r
-static HRESULT WINAPI DICF_CreateInstance(\r
- LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj\r
-) {\r
- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;\r
-\r
- TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);\r
- if ( IsEqualGUID( &IID_IDirectInputA, riid ) ||\r
- IsEqualGUID( &IID_IDirectInputW, riid ) ||\r
- IsEqualGUID( &IID_IDirectInput2A, riid ) ||\r
- IsEqualGUID( &IID_IDirectInput2W, riid ) ||\r
- IsEqualGUID( &IID_IDirectInput7A, riid ) ||\r
- IsEqualGUID( &IID_IDirectInput7W, riid ) ||\r
- IsEqualGUID( &IID_IDirectInput8A, riid ) ||\r
- IsEqualGUID( &IID_IDirectInput8W, riid ) ) {\r
- /* FIXME: reuse already created dinput if present? */\r
- return DirectInputCreateEx(0,0,riid,ppobj,pOuter);\r
- }\r
-\r
- FIXME("(%p,%p,%s,%p) Interface not found!\n",This,pOuter,debugstr_guid(riid),ppobj); \r
- return E_NOINTERFACE;\r
-}\r
-\r
-static HRESULT WINAPI DICF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {\r
- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;\r
- FIXME("(%p)->(%d),stub!\n",This,dolock);\r
- return S_OK;\r
-}\r
-\r
-static IClassFactoryVtbl DICF_Vtbl = {\r
- DICF_QueryInterface,\r
- DICF_AddRef,\r
- DICF_Release,\r
- DICF_CreateInstance,\r
- DICF_LockServer\r
-};\r
-static IClassFactoryImpl DINPUT_CF = {&DICF_Vtbl, 1 };\r
-\r
-/***********************************************************************\r
- * DllCanUnloadNow (DINPUT.@)\r
- */\r
-HRESULT WINAPI DINPUT_DllCanUnloadNow(void)\r
-{\r
- FIXME("(void): stub\n");\r
-\r
- return S_FALSE;\r
-}\r
-\r
-/***********************************************************************\r
- * DllGetClassObject (DINPUT.@)\r
- */\r
-HRESULT WINAPI DINPUT_DllGetClassObject(REFCLSID rclsid, REFIID riid,\r
- LPVOID *ppv)\r
-{\r
- TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);\r
- if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) {\r
- *ppv = (LPVOID)&DINPUT_CF;\r
- IClassFactory_AddRef((IClassFactory*)*ppv);\r
- return S_OK;\r
- }\r
-\r
- FIXME("(%s,%s,%p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);\r
- return CLASS_E_CLASSNOTAVAILABLE;\r
-}\r
+/* DirectInput
+ *
+ * Copyright 1998 Marcus Meissner
+ * Copyright 1998,1999 Lionel Ulmer
+ * Copyright 2000-2002 TransGaming Technologies Inc.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/* Status:
+ *
+ * - Tomb Raider 2 Demo:
+ * Playable using keyboard only.
+ * - WingCommander Prophecy Demo:
+ * Doesn't get Input Focus.
+ *
+ * - Fallout : works great in X and DGA mode
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <assert.h>
+#include <stdarg.h>
+#include <string.h>
+
+#define COBJMACROS
+
+#include "wine/debug.h"
+#include "wine/unicode.h"
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "winerror.h"
+#include "dinput_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dinput);
+
+static IDirectInput7AVtbl ddi7avt;
+static IDirectInput7WVtbl ddi7wvt;
+static IDirectInput8AVtbl ddi8avt;
+static IDirectInput8WVtbl ddi8wvt;
+
+/* This array will be filled a dinput.so loading */
+#define MAX_WINE_DINPUT_DEVICES 4
+static dinput_device * dinput_devices[MAX_WINE_DINPUT_DEVICES];
+static int nrof_dinput_devices = 0;
+
+HINSTANCE DINPUT_instance = NULL;
+
+BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserv)
+{
+ switch(reason)
+ {
+ case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls(inst);
+ DINPUT_instance = inst;
+ break;
+ case DLL_PROCESS_DETACH:
+ break;
+ }
+ return TRUE;
+}
+
+/* register a direct draw driver. We better not use malloc for we are in
+ * the ELF startup initialisation at this point.
+ */
+void dinput_register_device(dinput_device *device) {
+ int i;
+
+ /* insert according to priority */
+ for (i=0;i<nrof_dinput_devices;i++) {
+ if (dinput_devices[i]->pref <= device->pref) {
+ memcpy(dinput_devices+i+1,dinput_devices+i,sizeof(dinput_devices[0])*(nrof_dinput_devices-i));
+ dinput_devices[i] = device;
+ break;
+ }
+ }
+ if (i==nrof_dinput_devices) /* not found, or too low priority */
+ dinput_devices[nrof_dinput_devices] = device;
+
+ nrof_dinput_devices++;
+
+ /* increase MAX_DDRAW_DRIVERS if the line below triggers */
+ assert(nrof_dinput_devices <= MAX_WINE_DINPUT_DEVICES);
+}
+
+/******************************************************************************
+ * DirectInputCreateEx (DINPUT.@)
+ */
+HRESULT WINAPI DirectInputCreateEx(
+ HINSTANCE hinst, DWORD dwVersion, REFIID riid, LPVOID *ppDI,
+ LPUNKNOWN punkOuter)
+{
+ IDirectInputImpl* This;
+
+ TRACE("(0x%08lx,%04lx,%s,%p,%p)\n", (DWORD)hinst,dwVersion,debugstr_guid(riid),ppDI,punkOuter);
+
+ if (IsEqualGUID(&IID_IDirectInputA,riid) ||
+ IsEqualGUID(&IID_IDirectInput2A,riid) ||
+ IsEqualGUID(&IID_IDirectInput7A,riid)) {
+ This = (IDirectInputImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl));
+ This->lpVtbl = &ddi7avt;
+ This->ref = 1;
+ This->version = 1;
+ *ppDI = This;
+
+ return DI_OK;
+ }
+
+ if (IsEqualGUID(&IID_IDirectInputW,riid) ||
+ IsEqualGUID(&IID_IDirectInput2W,riid) ||
+ IsEqualGUID(&IID_IDirectInput7W,riid)) {
+ This = (IDirectInputImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl));
+ This->lpVtbl = &ddi7wvt;
+ This->ref = 1;
+ This->version = 1;
+ *ppDI = This;
+
+ return DI_OK;
+ }
+
+ if (IsEqualGUID(&IID_IDirectInput8A,riid)) {
+ This = (IDirectInputImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl));
+ This->lpVtbl = &ddi8avt;
+ This->ref = 1;
+ This->version = 8;
+ *ppDI = This;
+
+ return DI_OK;
+ }
+
+ if (IsEqualGUID(&IID_IDirectInput8W,riid)) {
+ This = (IDirectInputImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl));
+ This->lpVtbl = &ddi8wvt;
+ This->ref = 1;
+ This->version = 8;
+ *ppDI = This;
+
+ return DI_OK;
+ }
+
+ return DIERR_OLDDIRECTINPUTVERSION;
+}
+
+/******************************************************************************
+ * DirectInputCreateA (DINPUT.@)
+ */
+HRESULT WINAPI DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTA *ppDI, LPUNKNOWN punkOuter)
+{
+ IDirectInputImpl* This;
+ TRACE("(0x%08lx,%04lx,%p,%p)\n", (DWORD)hinst,dwVersion,ppDI,punkOuter);
+
+ //trace:dinput:DirectInputCreateA (0x00400000,0500,0x42bafc54,(nil))
+ This = (IDirectInputImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl));
+ This->lpVtbl = &ddi7avt;
+ This->ref = 1;
+ if (dwVersion > 0x0700) {
+ This->version = 8;
+ } else {
+ /* We do not differientiate between version 1, 2 and 7 */
+ This->version = 1;
+ }
+ *ppDI = (IDirectInputA*)This;
+ return 0;
+
+}
+
+/******************************************************************************
+ * DirectInputCreateW (DINPUT.@)
+ */
+HRESULT WINAPI DirectInputCreateW(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTW *ppDI, LPUNKNOWN punkOuter)
+{
+ IDirectInputImpl* This;
+ TRACE("(0x%08lx,%04lx,%p,%p)\n", (DWORD)hinst,dwVersion,ppDI,punkOuter);
+ This = (IDirectInputImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl));
+ This->lpVtbl = &ddi7wvt;
+ This->ref = 1;
+ if (dwVersion >= 0x0800) {
+ This->version = 8;
+ } else {
+ /* We do not differientiate between version 1, 2 and 7 */
+ This->version = 1;
+ }
+ *ppDI = (IDirectInputW*)This;
+ return 0;
+}
+
+static const char *_dump_DIDEVTYPE_value(DWORD dwDevType) {
+ switch (dwDevType) {
+ case 0: return "All devices";
+ case DIDEVTYPE_MOUSE: return "DIDEVTYPE_MOUSE";
+ case DIDEVTYPE_KEYBOARD: return "DIDEVTYPE_KEYBOARD";
+ case DIDEVTYPE_JOYSTICK: return "DIDEVTYPE_JOYSTICK";
+ case DIDEVTYPE_DEVICE: return "DIDEVTYPE_DEVICE";
+ default: return "Unkown";
+ }
+}
+
+static void _dump_EnumDevices_dwFlags(DWORD dwFlags) {
+ if (TRACE_ON(dinput)) {
+ unsigned int i;
+ static const struct {
+ DWORD mask;
+ const char *name;
+ } flags[] = {
+#define FE(x) { x, #x}
+ FE(DIEDFL_ALLDEVICES),
+ FE(DIEDFL_ATTACHEDONLY),
+ FE(DIEDFL_FORCEFEEDBACK),
+ FE(DIEDFL_INCLUDEALIASES),
+ FE(DIEDFL_INCLUDEPHANTOMS)
+#undef FE
+ };
+ if (dwFlags == 0) {
+ DPRINTF("DIEDFL_ALLDEVICES");
+ return;
+ }
+ for (i = 0; i < (sizeof(flags) / sizeof(flags[0])); i++)
+ if (flags[i].mask & dwFlags)
+ DPRINTF("%s ",flags[i].name);
+ }
+}
+
+/******************************************************************************
+ * IDirectInputA_EnumDevices
+ */
+static HRESULT WINAPI IDirectInputAImpl_EnumDevices(
+ LPDIRECTINPUT7A iface, DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback,
+ LPVOID pvRef, DWORD dwFlags)
+{
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+ DIDEVICEINSTANCEA devInstance;
+ int i, j, r;
+
+ TRACE("(this=%p,0x%04lx '%s',%p,%p,%04lx)\n",
+ This, dwDevType, _dump_DIDEVTYPE_value(dwDevType),
+ lpCallback, pvRef, dwFlags);
+
+ if (nrof_dinput_devices==0){
+ scan_mouse();
+ scan_keyboard();
+ }
+
+ TRACE(" flags: "); _dump_EnumDevices_dwFlags(dwFlags); TRACE("\n");
+
+
+ for (i = 0; i < nrof_dinput_devices; i++) {
+ for (j = 0, r = -1; r != 0; j++) {
+ devInstance.dwSize = sizeof(devInstance);
+ TRACE(" - checking device %d ('%s')\n", i, dinput_devices[i]->name);
+
+
+ if ((r = dinput_devices[i]->enum_deviceA(dwDevType, dwFlags, &devInstance, This->version, j))) {
+ if (lpCallback(&devInstance,pvRef) == DIENUM_STOP)
+ return 0;
+ }
+ }
+ }
+
+ return 0;
+}
+/******************************************************************************
+ * IDirectInputW_EnumDevices
+ */
+static HRESULT WINAPI IDirectInputWImpl_EnumDevices(
+ LPDIRECTINPUT7W iface, DWORD dwDevType, LPDIENUMDEVICESCALLBACKW lpCallback,
+ LPVOID pvRef, DWORD dwFlags)
+{
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+ DIDEVICEINSTANCEW devInstance;
+ int i, j, r;
+
+ if (nrof_dinput_devices==0){
+ scan_mouse();
+ scan_keyboard();
+ }
+
+ TRACE("(this=%p,0x%04lx '%s',%p,%p,%04lx)\n",
+ This, dwDevType, _dump_DIDEVTYPE_value(dwDevType),
+ lpCallback, pvRef, dwFlags);
+ TRACE(" flags: "); _dump_EnumDevices_dwFlags(dwFlags); TRACE("\n");
+
+
+ for (i = 0; i < nrof_dinput_devices; i++) {
+ for (j = 0, r = -1; r != 0; j++) {
+ devInstance.dwSize = sizeof(devInstance);
+ TRACE(" - checking device %d ('%s')\n", i, dinput_devices[i]->name);
+ if ((r = dinput_devices[i]->enum_deviceW(dwDevType, dwFlags, &devInstance, This->version, j))) {
+ if (lpCallback(&devInstance,pvRef) == DIENUM_STOP)
+ return 0;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static ULONG WINAPI IDirectInputAImpl_AddRef(LPDIRECTINPUT7A iface)
+{
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+ return InterlockedIncrement((&This->ref));
+}
+
+static ULONG WINAPI IDirectInputAImpl_Release(LPDIRECTINPUT7A iface)
+{
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+ ULONG ref;
+ ref = InterlockedDecrement(&(This->ref));
+ if (ref == 0)
+ HeapFree(GetProcessHeap(),0,This);
+ return ref;
+}
+
+static HRESULT WINAPI IDirectInputAImpl_QueryInterface(LPDIRECTINPUT7A iface, REFIID riid, LPVOID *ppobj) {
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+
+ TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+ if (IsEqualGUID(&IID_IUnknown,riid) ||
+ IsEqualGUID(&IID_IDirectInputA,riid) ||
+ IsEqualGUID(&IID_IDirectInput2A,riid) ||
+ IsEqualGUID(&IID_IDirectInput7A,riid)) {
+ IDirectInputAImpl_AddRef(iface);
+ *ppobj = This;
+ return 0;
+ }
+ TRACE("Unsupported interface !\n");
+ return E_FAIL;
+}
+
+static HRESULT WINAPI IDirectInputWImpl_QueryInterface(LPDIRECTINPUT7W iface, REFIID riid, LPVOID *ppobj) {
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+
+ TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+ if (IsEqualGUID(&IID_IUnknown,riid) ||
+ IsEqualGUID(&IID_IDirectInputW,riid) ||
+ IsEqualGUID(&IID_IDirectInput2W,riid) ||
+ IsEqualGUID(&IID_IDirectInput7W,riid)) {
+ IDirectInputAImpl_AddRef((LPDIRECTINPUT7A) iface);
+ *ppobj = This;
+ return 0;
+ }
+ TRACE("Unsupported interface !\n");
+ return E_FAIL;
+}
+
+static HRESULT WINAPI IDirectInputAImpl_CreateDevice(
+ LPDIRECTINPUT7A iface,REFGUID rguid,LPDIRECTINPUTDEVICEA* pdev,
+ LPUNKNOWN punk
+) {
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+ HRESULT ret_value = DIERR_DEVICENOTREG;
+ int i;
+
+ TRACE("(this=%p,%s,%p,%p)\n",This,debugstr_guid(rguid),pdev,punk);
+
+ if (nrof_dinput_devices==0){
+ scan_mouse();
+ scan_keyboard();
+ }
+
+ /* Loop on all the devices to see if anyone matches the given GUID */
+ for (i = 0; i < nrof_dinput_devices; i++) {
+ HRESULT ret;
+ if ((ret = dinput_devices[i]->create_deviceA(This, rguid, NULL, pdev)) == DI_OK)
+ return DI_OK;
+
+ if (ret == DIERR_NOINTERFACE)
+ ret_value = DIERR_NOINTERFACE;
+ }
+
+ return ret_value;
+}
+
+static HRESULT WINAPI IDirectInputWImpl_CreateDevice(LPDIRECTINPUT7A iface,
+ REFGUID rguid, LPDIRECTINPUTDEVICEW* pdev, LPUNKNOWN punk) {
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+ HRESULT ret_value = DIERR_DEVICENOTREG;
+ int i;
+
+ TRACE("(this=%p,%s,%p,%p)\n",This,debugstr_guid(rguid),pdev,punk);
+
+ if (nrof_dinput_devices==0){
+ scan_mouse();
+ scan_keyboard();
+ }
+
+ /* Loop on all the devices to see if anyone matches the given GUID */
+ for (i = 0; i < nrof_dinput_devices; i++) {
+ HRESULT ret;
+ if ((ret = dinput_devices[i]->create_deviceW(This, rguid, NULL, pdev)) == DI_OK)
+ return DI_OK;
+
+ if (ret == DIERR_NOINTERFACE)
+ ret_value = DIERR_NOINTERFACE;
+ }
+
+ return ret_value;
+}
+
+static HRESULT WINAPI IDirectInputAImpl_Initialize(LPDIRECTINPUT7A iface, HINSTANCE hinst, DWORD x) {
+ return DIERR_ALREADYINITIALIZED;
+}
+
+static HRESULT WINAPI IDirectInputAImpl_GetDeviceStatus(LPDIRECTINPUT7A iface,
+ REFGUID rguid) {
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+
+ FIXME("(%p)->(%s): stub\n",This,debugstr_guid(rguid));
+
+ return DI_OK;
+}
+
+static HRESULT WINAPI IDirectInputAImpl_RunControlPanel(LPDIRECTINPUT7A iface,
+ HWND hwndOwner,
+ DWORD dwFlags) {
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+ FIXME("(%p)->(%08lx,%08lx): stub\n",This, (DWORD) hwndOwner, dwFlags);
+
+ return DI_OK;
+}
+
+static HRESULT WINAPI IDirectInput2AImpl_FindDevice(LPDIRECTINPUT7A iface, REFGUID rguid,
+ LPCSTR pszName, LPGUID pguidInstance) {
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+ FIXME("(%p)->(%s, %s, %p): stub\n", This, debugstr_guid(rguid), pszName, pguidInstance);
+
+ return DI_OK;
+}
+
+static HRESULT WINAPI IDirectInput2WImpl_FindDevice(LPDIRECTINPUT7W iface, REFGUID rguid,
+ LPCWSTR pszName, LPGUID pguidInstance) {
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+ FIXME("(%p)->(%s, %s, %p): stub\n", This, debugstr_guid(rguid), debugstr_w(pszName), pguidInstance);
+
+ return DI_OK;
+}
+
+static HRESULT WINAPI IDirectInput7AImpl_CreateDeviceEx(LPDIRECTINPUT7A iface, REFGUID rguid,
+ REFIID riid, LPVOID* pvOut, LPUNKNOWN lpUnknownOuter)
+{
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+ HRESULT ret_value = DIERR_DEVICENOTREG;
+ int i;
+
+ TRACE("(%p)->(%s, %s, %p, %p)\n", This, debugstr_guid(rguid), debugstr_guid(riid), pvOut, lpUnknownOuter);
+
+ if (nrof_dinput_devices==0){
+ scan_mouse();
+ scan_keyboard();
+ }
+
+ /* Loop on all the devices to see if anyone matches the given GUID */
+ for (i = 0; i < nrof_dinput_devices; i++) {
+ HRESULT ret;
+ if ((ret = dinput_devices[i]->create_deviceA(This, rguid, riid, (LPDIRECTINPUTDEVICEA*) pvOut)) == DI_OK)
+ return DI_OK;
+
+ if (ret == DIERR_NOINTERFACE)
+ ret_value = DIERR_NOINTERFACE;
+ }
+
+ return ret_value;
+}
+
+static HRESULT WINAPI IDirectInput7WImpl_CreateDeviceEx(LPDIRECTINPUT7W iface, REFGUID rguid,
+ REFIID riid, LPVOID* pvOut, LPUNKNOWN lpUnknownOuter)
+{
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+ HRESULT ret_value = DIERR_DEVICENOTREG;
+ int i;
+
+ TRACE("(%p)->(%s, %s, %p, %p)\n", This, debugstr_guid(rguid), debugstr_guid(riid), pvOut, lpUnknownOuter);
+
+ if (nrof_dinput_devices==0){
+ scan_mouse();
+ scan_keyboard();
+ }
+
+
+
+ /* Loop on all the devices to see if anyone matches the given GUID */
+ for (i = 0; i < nrof_dinput_devices; i++) {
+ HRESULT ret;
+ if ((ret = dinput_devices[i]->create_deviceW(This, rguid, riid, (LPDIRECTINPUTDEVICEW*) pvOut)) == DI_OK)
+ return DI_OK;
+
+ if (ret == DIERR_NOINTERFACE)
+ ret_value = DIERR_NOINTERFACE;
+ }
+
+ return ret_value;
+}
+
+static HRESULT WINAPI IDirectInput8AImpl_QueryInterface(LPDIRECTINPUT8A iface, REFIID riid, LPVOID *ppobj) {
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+
+ TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+ if (IsEqualGUID(&IID_IUnknown,riid) ||
+ IsEqualGUID(&IID_IDirectInput8A,riid)) {
+ IDirectInputAImpl_AddRef((LPDIRECTINPUT7A) iface);
+ *ppobj = This;
+ return 0;
+ }
+ TRACE("Unsupported interface !\n");
+ return E_NOINTERFACE;
+}
+
+static HRESULT WINAPI IDirectInput8WImpl_QueryInterface(LPDIRECTINPUT8W iface, REFIID riid, LPVOID *ppobj) {
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+
+ TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+ if (IsEqualGUID(&IID_IUnknown,riid) ||
+ IsEqualGUID(&IID_IDirectInput8W,riid)) {
+ IDirectInputAImpl_AddRef((LPDIRECTINPUT7A) iface);
+ *ppobj = This;
+ return 0;
+ }
+ TRACE("Unsupported interface !\n");
+ return E_NOINTERFACE;
+}
+
+static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics(
+ LPDIRECTINPUT8A iface, LPCSTR ptszUserName, LPDIACTIONFORMATA lpdiActionFormat,
+ LPDIENUMDEVICESBYSEMANTICSCBA lpCallback,
+ LPVOID pvRef, DWORD dwFlags
+)
+{
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+
+ FIXME("(this=%p,%s,%p,%p,%p,%04lx): stub\n", This, ptszUserName, lpdiActionFormat,
+ lpCallback, pvRef, dwFlags);
+ return 0;
+}
+
+static HRESULT WINAPI IDirectInput8WImpl_EnumDevicesBySemantics(
+ LPDIRECTINPUT8W iface, LPCWSTR ptszUserName, LPDIACTIONFORMATW lpdiActionFormat,
+ LPDIENUMDEVICESBYSEMANTICSCBW lpCallback,
+ LPVOID pvRef, DWORD dwFlags
+)
+{
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+
+ FIXME("(this=%p,%s,%p,%p,%p,%04lx): stub\n", This, debugstr_w(ptszUserName), lpdiActionFormat,
+ lpCallback, pvRef, dwFlags);
+ return 0;
+}
+
+static HRESULT WINAPI IDirectInput8AImpl_ConfigureDevices(
+ LPDIRECTINPUT8A iface, LPDICONFIGUREDEVICESCALLBACK lpdiCallback,
+ LPDICONFIGUREDEVICESPARAMSA lpdiCDParams, DWORD dwFlags, LPVOID pvRefData
+)
+{
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+
+ FIXME("(this=%p,%p,%p,%04lx,%p): stub\n", This, lpdiCallback, lpdiCDParams,
+ dwFlags, pvRefData);
+ return 0;
+}
+
+static HRESULT WINAPI IDirectInput8WImpl_ConfigureDevices(
+ LPDIRECTINPUT8W iface, LPDICONFIGUREDEVICESCALLBACK lpdiCallback,
+ LPDICONFIGUREDEVICESPARAMSW lpdiCDParams, DWORD dwFlags, LPVOID pvRefData
+)
+{
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+
+ FIXME("(this=%p,%p,%p,%04lx,%p): stub\n", This, lpdiCallback, lpdiCDParams,
+ dwFlags, pvRefData);
+ return 0;
+}
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun) (typeof(ddi7avt.fun))
+#else
+# define XCAST(fun) (void*)
+#endif
+
+static IDirectInput7AVtbl ddi7avt = {
+ XCAST(QueryInterface)IDirectInputAImpl_QueryInterface,
+ XCAST(AddRef)IDirectInputAImpl_AddRef,
+ XCAST(Release)IDirectInputAImpl_Release,
+ XCAST(CreateDevice)IDirectInputAImpl_CreateDevice,
+ XCAST(EnumDevices)IDirectInputAImpl_EnumDevices,
+ XCAST(GetDeviceStatus)IDirectInputAImpl_GetDeviceStatus,
+ XCAST(RunControlPanel)IDirectInputAImpl_RunControlPanel,
+ XCAST(Initialize)IDirectInputAImpl_Initialize,
+ XCAST(FindDevice)IDirectInput2AImpl_FindDevice,
+ XCAST(CreateDeviceEx)IDirectInput7AImpl_CreateDeviceEx
+};
+
+#undef XCAST
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun) (typeof(ddi7wvt.fun))
+#else
+# define XCAST(fun) (void*)
+#endif
+
+static IDirectInput7WVtbl ddi7wvt = {
+ XCAST(QueryInterface)IDirectInputWImpl_QueryInterface,
+ XCAST(AddRef)IDirectInputAImpl_AddRef,
+ XCAST(Release)IDirectInputAImpl_Release,
+ XCAST(CreateDevice)IDirectInputWImpl_CreateDevice,
+ XCAST(EnumDevices)IDirectInputWImpl_EnumDevices,
+ XCAST(GetDeviceStatus)IDirectInputAImpl_GetDeviceStatus,
+ XCAST(RunControlPanel)IDirectInputAImpl_RunControlPanel,
+ XCAST(Initialize)IDirectInputAImpl_Initialize,
+ XCAST(FindDevice)IDirectInput2WImpl_FindDevice,
+ XCAST(CreateDeviceEx)IDirectInput7WImpl_CreateDeviceEx
+};
+#undef XCAST
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun) (typeof(ddi8avt.fun))
+#else
+# define XCAST(fun) (void*)
+#endif
+
+static IDirectInput8AVtbl ddi8avt = {
+ XCAST(QueryInterface)IDirectInput8AImpl_QueryInterface,
+ XCAST(AddRef)IDirectInputAImpl_AddRef,
+ XCAST(Release)IDirectInputAImpl_Release,
+ XCAST(CreateDevice)IDirectInputAImpl_CreateDevice,
+ XCAST(EnumDevices)IDirectInputAImpl_EnumDevices,
+ XCAST(GetDeviceStatus)IDirectInputAImpl_GetDeviceStatus,
+ XCAST(RunControlPanel)IDirectInputAImpl_RunControlPanel,
+ XCAST(Initialize)IDirectInputAImpl_Initialize,
+ XCAST(FindDevice)IDirectInput2AImpl_FindDevice,
+ XCAST(EnumDevicesBySemantics)IDirectInput8AImpl_EnumDevicesBySemantics,
+ XCAST(ConfigureDevices)IDirectInput8AImpl_ConfigureDevices
+};
+#undef XCAST
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun) (typeof(ddi8wvt.fun))
+#else
+# define XCAST(fun) (void*)
+#endif
+static IDirectInput8WVtbl ddi8wvt = {
+ XCAST(QueryInterface)IDirectInput8WImpl_QueryInterface,
+ XCAST(AddRef)IDirectInputAImpl_AddRef,
+ XCAST(Release)IDirectInputAImpl_Release,
+ XCAST(CreateDevice)IDirectInputWImpl_CreateDevice,
+ XCAST(EnumDevices)IDirectInputWImpl_EnumDevices,
+ XCAST(GetDeviceStatus)IDirectInputAImpl_GetDeviceStatus,
+ XCAST(RunControlPanel)IDirectInputAImpl_RunControlPanel,
+ XCAST(Initialize)IDirectInputAImpl_Initialize,
+ XCAST(FindDevice)IDirectInput2WImpl_FindDevice,
+ XCAST(EnumDevicesBySemantics)IDirectInput8WImpl_EnumDevicesBySemantics,
+ XCAST(ConfigureDevices)IDirectInput8WImpl_ConfigureDevices
+};
+#undef XCAST
+
+/*******************************************************************************
+ * DirectInput ClassFactory
+ */
+typedef struct
+{
+ /* IUnknown fields */
+ IClassFactoryVtbl *lpVtbl;
+ DWORD ref;
+} IClassFactoryImpl;
+
+static HRESULT WINAPI DICF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
+ IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+
+ FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI DICF_AddRef(LPCLASSFACTORY iface) {
+ IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+ return InterlockedIncrement(&(This->ref));
+}
+
+static ULONG WINAPI DICF_Release(LPCLASSFACTORY iface) {
+ IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+ /* static class, won't be freed */
+ return InterlockedDecrement(&(This->ref));
+}
+
+static HRESULT WINAPI DICF_CreateInstance(
+ LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
+) {
+ IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+
+ TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
+ if ( IsEqualGUID( &IID_IDirectInputA, riid ) ||
+ IsEqualGUID( &IID_IDirectInputW, riid ) ||
+ IsEqualGUID( &IID_IDirectInput2A, riid ) ||
+ IsEqualGUID( &IID_IDirectInput2W, riid ) ||
+ IsEqualGUID( &IID_IDirectInput7A, riid ) ||
+ IsEqualGUID( &IID_IDirectInput7W, riid ) ||
+ IsEqualGUID( &IID_IDirectInput8A, riid ) ||
+ IsEqualGUID( &IID_IDirectInput8W, riid ) ) {
+ /* FIXME: reuse already created dinput if present? */
+ return DirectInputCreateEx(0,0,riid,ppobj,pOuter);
+ }
+
+ FIXME("(%p,%p,%s,%p) Interface not found!\n",This,pOuter,debugstr_guid(riid),ppobj);
+ return E_NOINTERFACE;
+}
+
+static HRESULT WINAPI DICF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
+ IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+ FIXME("(%p)->(%d),stub!\n",This,dolock);
+ return S_OK;
+}
+
+static IClassFactoryVtbl DICF_Vtbl = {
+ DICF_QueryInterface,
+ DICF_AddRef,
+ DICF_Release,
+ DICF_CreateInstance,
+ DICF_LockServer
+};
+static IClassFactoryImpl DINPUT_CF = {&DICF_Vtbl, 1 };
+
+/***********************************************************************
+ * DllCanUnloadNow (DINPUT.@)
+ */
+HRESULT WINAPI DINPUT_DllCanUnloadNow(void)
+{
+ FIXME("(void): stub\n");
+
+ return S_FALSE;
+}
+
+/***********************************************************************
+ * DllGetClassObject (DINPUT.@)
+ */
+HRESULT WINAPI DINPUT_DllGetClassObject(REFCLSID rclsid, REFIID riid,
+ LPVOID *ppv)
+{
+ TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
+ if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) {
+ *ppv = (LPVOID)&DINPUT_CF;
+ IClassFactory_AddRef((IClassFactory*)*ppv);
+ return S_OK;
+ }
+
+ FIXME("(%s,%s,%p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
+ return CLASS_E_CLASSNOTAVAILABLE;
+}