From 6301e94e539b9c6bea3f8fb13f6668de0a87cd94 Mon Sep 17 00:00:00 2001 From: Lionel Ulmer Date: Sun, 5 Nov 2000 20:25:02 +0000 Subject: [PATCH] - reorganized DInput DLL - added stubbing for DInput 7a - 'fixed' the mouse problem in Fallout --- configure | 3 + configure.in | 3 + dlls/dinput/Makefile.in | 11 +- dlls/dinput/device.c | 538 ++++++++ dlls/dinput/device_private.h | 144 +++ dlls/dinput/dinput_main.c | 2225 ++-------------------------------- dlls/dinput/dinput_private.h | 26 + dlls/dinput/joystick/linux.c | 611 ++++++++++ dlls/dinput/keyboard/main.c | 307 +++++ dlls/dinput/mouse/main.c | 967 +++++++++++++++ include/dinput.h | 61 + 11 files changed, 2765 insertions(+), 2131 deletions(-) create mode 100644 dlls/dinput/device.c create mode 100644 dlls/dinput/device_private.h create mode 100644 dlls/dinput/dinput_private.h create mode 100644 dlls/dinput/joystick/linux.c create mode 100644 dlls/dinput/keyboard/main.c create mode 100644 dlls/dinput/mouse/main.c diff --git a/configure b/configure index 5ee50d6fbbd..db3edf9bad0 100755 --- a/configure +++ b/configure @@ -7003,6 +7003,9 @@ dlls/ddraw/ddraw \ dlls/ddraw/direct3d \ dlls/ddraw/dpalette \ dlls/ddraw/dsurface \ +dlls/dinput/joystick \ +dlls/dinput/keyboard \ +dlls/dinput/mouse \ dlls/kernel/messages \ dlls/user/resources \ " diff --git a/configure.in b/configure.in index 4c1313709cc..49907c847f0 100644 --- a/configure.in +++ b/configure.in @@ -1026,6 +1026,9 @@ dlls/ddraw/ddraw \ dlls/ddraw/direct3d \ dlls/ddraw/dpalette \ dlls/ddraw/dsurface \ +dlls/dinput/joystick \ +dlls/dinput/keyboard \ +dlls/dinput/mouse \ dlls/kernel/messages \ dlls/user/resources \ " diff --git a/dlls/dinput/Makefile.in b/dlls/dinput/Makefile.in index 7a69fa4f252..322e02ab5de 100644 --- a/dlls/dinput/Makefile.in +++ b/dlls/dinput/Makefile.in @@ -7,7 +7,16 @@ SOVERSION = 1.0 IMPORTS = user32 kernel32 ntdll C_SRCS = \ - dinput_main.c + device.c \ + dinput_main.c \ + joystick/linux.c \ + keyboard/main.c \ + mouse/main.c + +EXTRASUBDIRS = \ + joystick \ + keyboard \ + mouse @MAKE_DLL_RULES@ diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c new file mode 100644 index 00000000000..a7ca0ad3965 --- /dev/null +++ b/dlls/dinput/device.c @@ -0,0 +1,538 @@ +/* DirectInput Device + * + * Copyright 1998 Marcus Meissner + * Copyright 1998,1999 Lionel Ulmer + * + */ + +/* This file contains all the Device specific functions that can be used as stubs + by real device implementations. + + It also contains all the helper functions. +*/ +#include "config.h" + +#include "debugtools.h" +#include "winbase.h" +#include "winerror.h" +#include "windef.h" +#include "dinput.h" +#include "device_private.h" + +DEFAULT_DEBUG_CHANNEL(dinput); + +/****************************************************************************** + * Various debugging tools + */ +void _dump_cooperativelevel_DI(DWORD dwFlags) { + int i; + const struct { + DWORD mask; + char *name; + } flags[] = { +#define FE(x) { x, #x}, + FE(DISCL_BACKGROUND) + FE(DISCL_EXCLUSIVE) + FE(DISCL_FOREGROUND) + FE(DISCL_NONEXCLUSIVE) +#undef FE + }; + for (i=0;i> 8); +} + +void _dump_DIPROPHEADER(DIPROPHEADER *diph) { + DPRINTF(" - dwObj = 0x%08lx\n", diph->dwObj); + DPRINTF(" - dwHow = %s\n", + ((diph->dwHow == DIPH_DEVICE) ? "DIPH_DEVICE" : + ((diph->dwHow == DIPH_BYOFFSET) ? "DIPH_BYOFFSET" : + ((diph->dwHow == DIPH_BYID)) ? "DIPH_BYID" : "unknown"))); +} + +void _dump_OBJECTINSTANCEA(DIDEVICEOBJECTINSTANCEA *ddoi) { + if (TRACE_ON(dinput)) { + DPRINTF(" - enumerating : 0x%08lx - %2ld - 0x%08lx - %s\n", + ddoi->guidType.Data1, ddoi->dwOfs, ddoi->dwType, ddoi->tszName); + } +} + +/* Conversion between internal data buffer and external data buffer */ +void fill_DataFormat(void *out, void *in, DataFormat *df) { + int i; + char *in_c = (char *) in; + char *out_c = (char *) out; + + if (df->dt == NULL) { + /* This means that the app uses Wine's internal data format */ + memcpy(out, in, df->internal_format_size); + } else { + for (i = 0; i < df->size; i++) { + if (df->dt[i].offset_in >= 0) { + switch (df->dt[i].size) { + case 1: + TRACE("Copying (c) to %d from %d (value %d)\n", + df->dt[i].offset_out, df->dt[i].offset_in, *((char *) (in_c + df->dt[i].offset_in))); + *((char *) (out_c + df->dt[i].offset_out)) = *((char *) (in_c + df->dt[i].offset_in)); + break; + + case 2: + TRACE("Copying (s) to %d from %d (value %d)\n", + df->dt[i].offset_out, df->dt[i].offset_in, *((short *) (in_c + df->dt[i].offset_in))); + *((short *) (out_c + df->dt[i].offset_out)) = *((short *) (in_c + df->dt[i].offset_in)); + break; + + case 4: + TRACE("Copying (i) to %d from %d (value %d)\n", + df->dt[i].offset_out, df->dt[i].offset_in, *((int *) (in_c + df->dt[i].offset_in))); + *((int *) (out_c + df->dt[i].offset_out)) = *((int *) (in_c + df->dt[i].offset_in)); + break; + + default: + memcpy((out_c + df->dt[i].offset_out), (in_c + df->dt[i].offset_in), df->dt[i].size); + } + } else { + switch (df->dt[i].size) { + case 1: + TRACE("Copying (c) to %d default value %d\n", + df->dt[i].offset_out, df->dt[i].value); + *((char *) (out_c + df->dt[i].offset_out)) = (char) df->dt[i].value; + break; + + case 2: + TRACE("Copying (s) to %d default value %d\n", + df->dt[i].offset_out, df->dt[i].value); + *((short *) (out_c + df->dt[i].offset_out)) = (short) df->dt[i].value; + break; + + case 4: + TRACE("Copying (i) to %d default value %d\n", + df->dt[i].offset_out, df->dt[i].value); + *((int *) (out_c + df->dt[i].offset_out)) = (int) df->dt[i].value; + break; + + default: + memset((out_c + df->dt[i].offset_out), df->dt[i].size, 0); + } + } + } + } +} + +DataFormat *create_DataFormat(DIDATAFORMAT *wine_format, LPCDIDATAFORMAT asked_format, int *offset) { + DataFormat *ret; + DataTransform *dt; + int i, j; + int same = 1; + int *done; + int index = 0; + + ret = (DataFormat *) HeapAlloc(GetProcessHeap(), 0, sizeof(DataFormat)); + + done = (int *) HeapAlloc(GetProcessHeap(), 0, sizeof(int) * asked_format->dwNumObjs); + memset(done, 0, sizeof(int) * asked_format->dwNumObjs); + + dt = (DataTransform *) HeapAlloc(GetProcessHeap(), 0, asked_format->dwNumObjs * sizeof(DataTransform)); + + TRACE("Creating DataTransorm : \n"); + + for (i = 0; i < wine_format->dwNumObjs; i++) { + offset[i] = -1; + + for (j = 0; j < asked_format->dwNumObjs; j++) { + if (done[j] == 1) + continue; + + if (((asked_format->rgodf[j].pguid == NULL) || (IsEqualGUID(wine_format->rgodf[i].pguid, asked_format->rgodf[j].pguid))) + && + (wine_format->rgodf[i].dwType & asked_format->rgodf[j].dwType)) { + + done[j] = 1; + + TRACE("Matching : \n"); + TRACE(" - Asked (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n", + j, debugstr_guid(asked_format->rgodf[j].pguid), + asked_format->rgodf[j].dwOfs, + DIDFT_GETTYPE(asked_format->rgodf[j].dwType), DIDFT_GETINSTANCE(asked_format->rgodf[j].dwType)); + + TRACE(" - Wine (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n", + j, debugstr_guid(wine_format->rgodf[i].pguid), + wine_format->rgodf[i].dwOfs, + DIDFT_GETTYPE(wine_format->rgodf[i].dwType), DIDFT_GETINSTANCE(wine_format->rgodf[i].dwType)); + + if (wine_format->rgodf[i].dwType & DIDFT_BUTTON) + dt[index].size = sizeof(BYTE); + else + dt[index].size = sizeof(DWORD); + dt[index].offset_in = wine_format ->rgodf[i].dwOfs; + dt[index].offset_out = asked_format->rgodf[j].dwOfs; + dt[index].value = 0; + index++; + + if (wine_format->rgodf[i].dwOfs != asked_format->rgodf[j].dwOfs) + same = 0; + + offset[i] = asked_format->rgodf[j].dwOfs; + break; + } + } + + if (j == asked_format->dwNumObjs) + same = 0; + } + + TRACE("Setting to default value :\n"); + for (j = 0; j < asked_format->dwNumObjs; j++) { + if (done[j] == 0) { + TRACE(" - Asked (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n", + j, debugstr_guid(asked_format->rgodf[j].pguid), + asked_format->rgodf[j].dwOfs, + DIDFT_GETTYPE(asked_format->rgodf[j].dwType), DIDFT_GETINSTANCE(asked_format->rgodf[j].dwType)); + + + if (asked_format->rgodf[j].dwType & DIDFT_BUTTON) + dt[index].size = sizeof(BYTE); + else + dt[index].size = sizeof(DWORD); + dt[index].offset_in = -1; + dt[index].offset_out = asked_format->rgodf[j].dwOfs; + dt[index].value = 0; + index++; + + same = 0; + } + } + + ret->internal_format_size = wine_format->dwDataSize; + ret->size = index; + if (same) { + ret->dt = NULL; + HeapFree(GetProcessHeap(), 0, dt); + } else { + ret->dt = dt; + } + + HeapFree(GetProcessHeap(), 0, done); + + return ret; +} + +/****************************************************************************** + * IDirectInputDeviceA + */ + +HRESULT WINAPI IDirectInputDevice2AImpl_SetDataFormat( + LPDIRECTINPUTDEVICE2A iface,LPCDIDATAFORMAT df +) { + int i; + ICOM_THIS(IDirectInputDevice2AImpl,iface); + + TRACE("(this=%p,%p)\n",This,df); + + TRACE("df.dwSize=%ld\n",df->dwSize); + TRACE("(df.dwObjsize=%ld)\n",df->dwObjSize); + TRACE("(df.dwFlags=0x%08lx)\n",df->dwFlags); + TRACE("(df.dwDataSize=%ld)\n",df->dwDataSize); + TRACE("(df.dwNumObjs=%ld)\n",df->dwNumObjs); + + for (i=0;idwNumObjs;i++) { + TRACE("df.rgodf[%d].guid %s\n",i,debugstr_guid(df->rgodf[i].pguid)); + TRACE("df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs); + TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType)); + TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags); + } + return 0; +} + +HRESULT WINAPI IDirectInputDevice2AImpl_SetCooperativeLevel( + LPDIRECTINPUTDEVICE2A iface,HWND hwnd,DWORD dwflags +) { + ICOM_THIS(IDirectInputDevice2AImpl,iface); + TRACE("(this=%p,0x%08lx,0x%08lx)\n",This,(DWORD)hwnd,dwflags); + if (TRACE_ON(dinput)) + _dump_cooperativelevel_DI(dwflags); + return 0; +} + +HRESULT WINAPI IDirectInputDevice2AImpl_SetEventNotification( + LPDIRECTINPUTDEVICE2A iface,HANDLE hnd +) { + ICOM_THIS(IDirectInputDevice2AImpl,iface); + FIXME("(this=%p,0x%08lx): stub\n",This,(DWORD)hnd); + return 0; +} + +ULONG WINAPI IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE2A iface) +{ + ICOM_THIS(IDirectInputDevice2AImpl,iface); + This->ref--; + if (This->ref) + return This->ref; + HeapFree(GetProcessHeap(),0,This); + return 0; +} + +HRESULT WINAPI IDirectInputDevice2AImpl_QueryInterface( + LPDIRECTINPUTDEVICE2A iface,REFIID riid,LPVOID *ppobj +) +{ + ICOM_THIS(IDirectInputDevice2AImpl,iface); + + TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); + if (IsEqualGUID(&IID_IUnknown,riid)) { + IDirectInputDevice2_AddRef(iface); + *ppobj = This; + return 0; + } + if (IsEqualGUID(&IID_IDirectInputDeviceA,riid)) { + IDirectInputDevice2_AddRef(iface); + *ppobj = This; + return 0; + } + if (IsEqualGUID(&IID_IDirectInputDevice2A,riid)) { + IDirectInputDevice2_AddRef(iface); + *ppobj = This; + return 0; + } + TRACE("Unsupported interface !\n"); + return E_FAIL; +} + +ULONG WINAPI IDirectInputDevice2AImpl_AddRef( + LPDIRECTINPUTDEVICE2A iface) +{ + ICOM_THIS(IDirectInputDevice2AImpl,iface); + return ++This->ref; +} + +HRESULT WINAPI IDirectInputDevice2AImpl_EnumObjects( + LPDIRECTINPUTDEVICE2A iface, + LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback, + LPVOID lpvRef, + DWORD dwFlags) +{ + FIXME("(this=%p,%p,%p,%08lx): stub!\n", iface, lpCallback, lpvRef, dwFlags); + if (TRACE_ON(dinput)) { + DPRINTF(" - flags = "); + _dump_EnumObjects_flags(dwFlags); + DPRINTF("\n"); + } + + return DI_OK; +} + +HRESULT WINAPI IDirectInputDevice2AImpl_GetProperty( + LPDIRECTINPUTDEVICE2A iface, + REFGUID rguid, + LPDIPROPHEADER pdiph) +{ + FIXME("(this=%p,%s,%p): stub!\n", + iface, debugstr_guid(rguid), pdiph); + + if (TRACE_ON(dinput)) + _dump_DIPROPHEADER(pdiph); + + return DI_OK; +} + +HRESULT WINAPI IDirectInputDevice2AImpl_GetObjectInfo( + LPDIRECTINPUTDEVICE2A iface, + LPDIDEVICEOBJECTINSTANCEA pdidoi, + DWORD dwObj, + DWORD dwHow) +{ + FIXME("(this=%p,%p,%ld,0x%08lx): stub!\n", + iface, pdidoi, dwObj, dwHow); + + return DI_OK; +} + +HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceInfo( + LPDIRECTINPUTDEVICE2A iface, + LPDIDEVICEINSTANCEA pdidi) +{ + FIXME("(this=%p,%p): stub!\n", + iface, pdidi); + + return DI_OK; +} + +HRESULT WINAPI IDirectInputDevice2AImpl_RunControlPanel( + LPDIRECTINPUTDEVICE2A iface, + HWND hwndOwner, + DWORD dwFlags) +{ + FIXME("(this=%p,0x%08x,0x%08lx): stub!\n", + iface, hwndOwner, dwFlags); + + return DI_OK; +} + +HRESULT WINAPI IDirectInputDevice2AImpl_Initialize( + LPDIRECTINPUTDEVICE2A iface, + HINSTANCE hinst, + DWORD dwVersion, + REFGUID rguid) +{ + FIXME("(this=%p,%d,%ld,%s): stub!\n", + iface, hinst, dwVersion, debugstr_guid(rguid)); + return DI_OK; +} + +/****************************************************************************** + * IDirectInputDevice2A + */ + +HRESULT WINAPI IDirectInputDevice2AImpl_CreateEffect( + LPDIRECTINPUTDEVICE2A iface, + REFGUID rguid, + LPCDIEFFECT lpeff, + LPDIRECTINPUTEFFECT *ppdef, + LPUNKNOWN pUnkOuter) +{ + FIXME("(this=%p,%s,%p,%p,%p): stub!\n", + iface, debugstr_guid(rguid), lpeff, ppdef, pUnkOuter); + return DI_OK; +} + +HRESULT WINAPI IDirectInputDevice2AImpl_EnumEffects( + LPDIRECTINPUTDEVICE2A iface, + LPDIENUMEFFECTSCALLBACKA lpCallback, + LPVOID lpvRef, + DWORD dwFlags) +{ + FIXME("(this=%p,%p,%p,0x%08lx): stub!\n", + iface, lpCallback, lpvRef, dwFlags); + + if (lpCallback) + lpCallback(NULL, lpvRef); + return DI_OK; +} + +HRESULT WINAPI IDirectInputDevice2AImpl_GetEffectInfo( + LPDIRECTINPUTDEVICE2A iface, + LPDIEFFECTINFOA lpdei, + REFGUID rguid) +{ + FIXME("(this=%p,%p,%s): stub!\n", + iface, lpdei, debugstr_guid(rguid)); + return DI_OK; +} + +HRESULT WINAPI IDirectInputDevice2AImpl_GetForceFeedbackState( + LPDIRECTINPUTDEVICE2A iface, + LPDWORD pdwOut) +{ + FIXME("(this=%p,%p): stub!\n", + iface, pdwOut); + return DI_OK; +} + +HRESULT WINAPI IDirectInputDevice2AImpl_SendForceFeedbackCommand( + LPDIRECTINPUTDEVICE2A iface, + DWORD dwFlags) +{ + FIXME("(this=%p,0x%08lx): stub!\n", + iface, dwFlags); + return DI_OK; +} + +HRESULT WINAPI IDirectInputDevice2AImpl_EnumCreatedEffectObjects( + LPDIRECTINPUTDEVICE2A iface, + LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, + LPVOID lpvRef, + DWORD dwFlags) +{ + FIXME("(this=%p,%p,%p,0x%08lx): stub!\n", + iface, lpCallback, lpvRef, dwFlags); + if (lpCallback) + lpCallback(NULL, lpvRef); + return DI_OK; +} + +HRESULT WINAPI IDirectInputDevice2AImpl_Escape( + LPDIRECTINPUTDEVICE2A iface, + LPDIEFFESCAPE lpDIEEsc) +{ + FIXME("(this=%p,%p): stub!\n", + iface, lpDIEEsc); + return DI_OK; +} + +HRESULT WINAPI IDirectInputDevice2AImpl_Poll( + LPDIRECTINPUTDEVICE2A iface) +{ + FIXME("(this=%p): stub!\n", + iface); + return DI_OK; +} + +HRESULT WINAPI IDirectInputDevice2AImpl_SendDeviceData( + LPDIRECTINPUTDEVICE2A iface, + DWORD cbObjectData, + LPDIDEVICEOBJECTDATA rgdod, + LPDWORD pdwInOut, + DWORD dwFlags) +{ + FIXME("(this=%p,0x%08lx,%p,%p,0x%08lx): stub!\n", + iface, cbObjectData, rgdod, pdwInOut, dwFlags); + + return DI_OK; +} + +HRESULT WINAPI IDirectInputDevice7AImpl_EnumEffectsInFile(LPDIRECTINPUTDEVICE7A iface, + LPCSTR lpszFileName, + LPDIENUMEFFECTSINFILECALLBACK pec, + LPVOID pvRef, + DWORD dwFlags) +{ + FIXME("(%p)->(%s,%p,%p,%08lx): stub !\n", iface, lpszFileName, pec, pvRef, dwFlags); + + return DI_OK; +} + +HRESULT WINAPI IDirectInputDevice7AImpl_WriteEffectToFile(LPDIRECTINPUTDEVICE7A iface, + LPCSTR lpszFileName, + DWORD dwEntries, + LPDIFILEEFFECT rgDiFileEft, + DWORD dwFlags) +{ + FIXME("(%p)->(%s,%08lx,%p,%08lx): stub !\n", iface, lpszFileName, dwEntries, rgDiFileEft, dwFlags); + + return DI_OK; +} diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h new file mode 100644 index 00000000000..8cb8924d757 --- /dev/null +++ b/dlls/dinput/device_private.h @@ -0,0 +1,144 @@ +#ifndef __WINE_DLLS_DINPUT_DINPUTDEVICE_PRIVATE_H +#define __WINE_DLLS_DINPUT_DINPUTDEVICE_PRIVATE_H + +#include "winbase.h" +#include "dinput.h" + +/* Device implementation */ +typedef struct IDirectInputDevice2AImpl IDirectInputDevice2AImpl; +struct IDirectInputDevice2AImpl +{ + ICOM_VFIELD(IDirectInputDevice2A); + DWORD ref; + GUID guid; +}; + +/* Routines to do DataFormat / WineFormat conversions */ +typedef struct { + int size; + int offset_in; + int offset_out; + int value; +} DataTransform; + +typedef struct { + int size; + int internal_format_size; + DataTransform *dt; +} DataFormat; +extern void fill_DataFormat(void *out, void *in, DataFormat *df) ; +extern DataFormat *create_DataFormat(DIDATAFORMAT *wine_format, LPCDIDATAFORMAT asked_format, int *offset) ; + +/* Used to fill events in the queue */ +#define GEN_EVENT(offset,data,xtime,seq) \ +{ \ + /* If queue_len > 0, queuing is requested -> TRACE the event queued */ \ + if (This->queue_len > 0) { \ + TRACE(" queueing %d at offset %d (queue pos %d / size %d)\n", \ + (int) (data), (int) (offset), \ + (int) (This->queue_pos), (int) (This->queue_len)); \ + \ + if ((offset >= 0) && (This->queue_pos < This->queue_len)) { \ + This->data_queue[This->queue_pos].dwOfs = offset; \ + This->data_queue[This->queue_pos].dwData = data; \ + This->data_queue[This->queue_pos].dwTimeStamp = xtime; \ + This->data_queue[This->queue_pos].dwSequence = seq; \ + This->queue_pos++; \ + } \ + } \ +} + + +/* Various debug tools */ +extern void _dump_cooperativelevel_DI(DWORD dwFlags) ; +extern void _dump_EnumObjects_flags(DWORD dwFlags) ; +extern void _dump_DIPROPHEADER(DIPROPHEADER *diph) ; +extern void _dump_OBJECTINSTANCEA(DIDEVICEOBJECTINSTANCEA *ddoi) ; + +/* And the stubs */ +extern HRESULT WINAPI IDirectInputDevice2AImpl_SetDataFormat( + LPDIRECTINPUTDEVICE2A iface,LPCDIDATAFORMAT df ) ; +extern HRESULT WINAPI IDirectInputDevice2AImpl_SetCooperativeLevel( + LPDIRECTINPUTDEVICE2A iface,HWND hwnd,DWORD dwflags ) ; +extern HRESULT WINAPI IDirectInputDevice2AImpl_SetEventNotification( + LPDIRECTINPUTDEVICE2A iface,HANDLE hnd ) ; +extern ULONG WINAPI IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE2A iface) ; +extern HRESULT WINAPI IDirectInputDevice2AImpl_QueryInterface( + LPDIRECTINPUTDEVICE2A iface,REFIID riid,LPVOID *ppobj ) ; +extern ULONG WINAPI IDirectInputDevice2AImpl_AddRef( + LPDIRECTINPUTDEVICE2A iface) ; +extern HRESULT WINAPI IDirectInputDevice2AImpl_EnumObjects( + LPDIRECTINPUTDEVICE2A iface, + LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback, + LPVOID lpvRef, + DWORD dwFlags) ; +extern HRESULT WINAPI IDirectInputDevice2AImpl_GetProperty( + LPDIRECTINPUTDEVICE2A iface, + REFGUID rguid, + LPDIPROPHEADER pdiph) ; +extern HRESULT WINAPI IDirectInputDevice2AImpl_GetObjectInfo( + LPDIRECTINPUTDEVICE2A iface, + LPDIDEVICEOBJECTINSTANCEA pdidoi, + DWORD dwObj, + DWORD dwHow) ; +extern HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceInfo( + LPDIRECTINPUTDEVICE2A iface, + LPDIDEVICEINSTANCEA pdidi) ; +extern HRESULT WINAPI IDirectInputDevice2AImpl_RunControlPanel( + LPDIRECTINPUTDEVICE2A iface, + HWND hwndOwner, + DWORD dwFlags) ; +extern HRESULT WINAPI IDirectInputDevice2AImpl_Initialize( + LPDIRECTINPUTDEVICE2A iface, + HINSTANCE hinst, + DWORD dwVersion, + REFGUID rguid) ; +extern HRESULT WINAPI IDirectInputDevice2AImpl_CreateEffect( + LPDIRECTINPUTDEVICE2A iface, + REFGUID rguid, + LPCDIEFFECT lpeff, + LPDIRECTINPUTEFFECT *ppdef, + LPUNKNOWN pUnkOuter) ; +extern HRESULT WINAPI IDirectInputDevice2AImpl_EnumEffects( + LPDIRECTINPUTDEVICE2A iface, + LPDIENUMEFFECTSCALLBACKA lpCallback, + LPVOID lpvRef, + DWORD dwFlags) ; +extern HRESULT WINAPI IDirectInputDevice2AImpl_GetEffectInfo( + LPDIRECTINPUTDEVICE2A iface, + LPDIEFFECTINFOA lpdei, + REFGUID rguid) ; +extern HRESULT WINAPI IDirectInputDevice2AImpl_GetForceFeedbackState( + LPDIRECTINPUTDEVICE2A iface, + LPDWORD pdwOut) ; +extern HRESULT WINAPI IDirectInputDevice2AImpl_SendForceFeedbackCommand( + LPDIRECTINPUTDEVICE2A iface, + DWORD dwFlags) ; +extern HRESULT WINAPI IDirectInputDevice2AImpl_EnumCreatedEffectObjects( + LPDIRECTINPUTDEVICE2A iface, + LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, + LPVOID lpvRef, + DWORD dwFlags) ; +extern HRESULT WINAPI IDirectInputDevice2AImpl_Escape( + LPDIRECTINPUTDEVICE2A iface, + LPDIEFFESCAPE lpDIEEsc) ; +extern HRESULT WINAPI IDirectInputDevice2AImpl_Poll( + LPDIRECTINPUTDEVICE2A iface) ; +extern HRESULT WINAPI IDirectInputDevice2AImpl_SendDeviceData( + LPDIRECTINPUTDEVICE2A iface, + DWORD cbObjectData, + LPDIDEVICEOBJECTDATA rgdod, + LPDWORD pdwInOut, + DWORD dwFlags) ; +extern HRESULT WINAPI IDirectInputDevice7AImpl_EnumEffectsInFile(LPDIRECTINPUTDEVICE7A iface, + LPCSTR lpszFileName, + LPDIENUMEFFECTSINFILECALLBACK pec, + LPVOID pvRef, + DWORD dwFlags) ; +extern HRESULT WINAPI IDirectInputDevice7AImpl_WriteEffectToFile(LPDIRECTINPUTDEVICE7A iface, + LPCSTR lpszFileName, + DWORD dwEntries, + LPDIFILEEFFECT rgDiFileEft, + DWORD dwFlags) ; + +#endif /* __WINE_DLLS_DINPUT_DINPUTDEVICE_PRIVATE_H */ diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index 40eab386d9e..7a49625aaaf 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -19,463 +19,35 @@ */ #include "config.h" -#include -#include -#include -#include #include -#ifdef HAVE_SYS_SIGNAL_H -# include -#endif -#include -#include -#include -#include -#ifdef HAVE_SYS_ERRNO_H -# include -#endif -#ifdef HAVE_LINUX_JOYSTICK_H -# include -# define JOYDEV "/dev/js0" -#endif #include "debugtools.h" -#include "input.h" -#include "user.h" -#include "mouse.h" #include "winbase.h" #include "winerror.h" #include "windef.h" -#include "wingdi.h" -#include "winuser.h" #include "initguid.h" #include "dinput.h" +#include "dinput_private.h" DEFAULT_DEBUG_CHANNEL(dinput); -/* Wine mouse driver object instances */ -#define WINE_MOUSE_X_AXIS_INSTANCE 0x0001 -#define WINE_MOUSE_Y_AXIS_INSTANCE 0x0002 -#define WINE_MOUSE_L_BUTTON_INSTANCE 0x0004 -#define WINE_MOUSE_R_BUTTON_INSTANCE 0x0008 -#define WINE_MOUSE_M_BUTTON_INSTANCE 0x0010 - -/* Wine joystick driver object instances */ -#define WINE_JOYSTICK_AXIS_BASE 0 -#define WINE_JOYSTICK_BUTTON_BASE 8 - -extern BYTE InputKeyStateTable[256]; -extern int min_keycode, max_keycode; -extern WORD keyc2vkey[256]; - -/* Routines to do DataFormat / WineFormat conversions */ -typedef struct { - int size; - int offset_in; - int offset_out; - int value; -} DataTransform; - -typedef struct { - int size; - int internal_format_size; - DataTransform *dt; -} DataFormat; - -/* ------------------------------- */ -/* Wine mouse internal data format */ -/* ------------------------------- */ - -/* Constants used to access the offset array */ -#define WINE_MOUSE_X_POSITION 0 -#define WINE_MOUSE_Y_POSITION 1 -#define WINE_MOUSE_L_POSITION 2 -#define WINE_MOUSE_R_POSITION 3 -#define WINE_MOUSE_M_POSITION 4 - -typedef struct { - LONG lX; - LONG lY; - BYTE rgbButtons[4]; -} Wine_InternalMouseData; - -#define WINE_INTERNALMOUSE_NUM_OBJS 5 - -static DIOBJECTDATAFORMAT Wine_InternalMouseObjectFormat[WINE_INTERNALMOUSE_NUM_OBJS] = { - { &GUID_XAxis, FIELD_OFFSET(Wine_InternalMouseData, lX), - DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS, 0 }, - { &GUID_YAxis, FIELD_OFFSET(Wine_InternalMouseData, lY), - DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS, 0 }, - { &GUID_Button, (FIELD_OFFSET(Wine_InternalMouseData, rgbButtons)) + 0, - DIDFT_MAKEINSTANCE(WINE_MOUSE_L_BUTTON_INSTANCE) | DIDFT_PSHBUTTON, 0 }, - { &GUID_Button, (FIELD_OFFSET(Wine_InternalMouseData, rgbButtons)) + 1, - DIDFT_MAKEINSTANCE(WINE_MOUSE_R_BUTTON_INSTANCE) | DIDFT_PSHBUTTON, 0 }, - { &GUID_Button, (FIELD_OFFSET(Wine_InternalMouseData, rgbButtons)) + 2, - DIDFT_MAKEINSTANCE(WINE_MOUSE_M_BUTTON_INSTANCE) | DIDFT_PSHBUTTON, 0 } -}; - -static DIDATAFORMAT Wine_InternalMouseFormat = { - 0, /* dwSize - unused */ - 0, /* dwObjsize - unused */ - 0, /* dwFlags - unused */ - sizeof(Wine_InternalMouseData), - WINE_INTERNALMOUSE_NUM_OBJS, /* dwNumObjs */ - Wine_InternalMouseObjectFormat -}; - static ICOM_VTABLE(IDirectInputA) ddiavt; -static ICOM_VTABLE(IDirectInputDevice2A) SysKeyboardAvt; -static ICOM_VTABLE(IDirectInputDevice2A) SysMouseAvt; +static ICOM_VTABLE(IDirectInput7A) ddi7avt; -typedef struct IDirectInputAImpl IDirectInputAImpl; -typedef struct IDirectInputDevice2AImpl IDirectInputDevice2AImpl; -typedef struct SysKeyboardAImpl SysKeyboardAImpl; -typedef struct SysMouseAImpl SysMouseAImpl; +/* This array will be filled a dinput.so loading */ +#define MAX_WINE_DINPUT_DEVICES 3 +static dinput_device * dinput_devices[MAX_WINE_DINPUT_DEVICES]; +static int nrof_dinput_devices = 0; -struct IDirectInputDevice2AImpl -{ - ICOM_VFIELD(IDirectInputDevice2A); - DWORD ref; - GUID guid; -}; - -struct SysKeyboardAImpl -{ - /* IDirectInputDevice2AImpl */ - ICOM_VFIELD(IDirectInputDevice2A); - DWORD ref; - GUID guid; - /* SysKeyboardAImpl */ - BYTE keystate[256]; - KEYBOARD_CONFIG initial_config; - int acquired; -}; - -#ifdef HAVE_LINUX_22_JOYSTICK_API -typedef struct JoystickAImpl JoystickAImpl; -static ICOM_VTABLE(IDirectInputDevice2A) JoystickAvt; -struct JoystickAImpl -{ - /* IDirectInputDevice2AImpl */ - ICOM_VFIELD(IDirectInputDevice2A); - DWORD ref; - GUID guid; - - /* joystick private */ - int joyfd; - LPDIDATAFORMAT df; - HANDLE hEvent; - LONG lMin,lMax,deadzone; - LPDIDEVICEOBJECTDATA data_queue; - int queue_pos, queue_len; - DIJOYSTATE js; -}; -#endif - -typedef enum { - WARP_NEEDED, /* Warping is needed */ - WARP_STARTED, /* Warping has been done, waiting for the warp event */ - WARP_DONE /* Warping has been done */ -} WARP_STATUS; - -struct SysMouseAImpl -{ - /* IDirectInputDevice2AImpl */ - ICOM_VFIELD(IDirectInputDevice2A); - DWORD ref; - GUID guid; - - /* The current data format and the conversion between internal - and external data formats */ - LPDIDATAFORMAT df; - DataFormat *wine_df; - int offset_array[5]; - - /* SysMouseAImpl */ - BYTE absolute; - /* Previous position for relative moves */ - LONG prevX, prevY; - LPMOUSE_EVENT_PROC prev_handler; - HWND win; - DWORD win_centerX, win_centerY; - LPDIDEVICEOBJECTDATA data_queue; - int queue_pos, queue_len; - WARP_STATUS need_warp; - int acquired; - HANDLE hEvent; - CRITICAL_SECTION crit; - - /* This is for mouse reporting. */ - Wine_InternalMouseData m_state; -}; - -static int evsequence=0; - - -/* UIDs for Wine "drivers". - When enumerating each device supporting DInput, they have two UIDs : - - the 'windows' UID - - a vendor UID */ -#ifdef HAVE_LINUX_22_JOYSTICK_API -static GUID DInput_Wine_Joystick_GUID = { /* 9e573ed9-7734-11d2-8d4a-23903fb6bdf7 */ - 0x9e573ed9, - 0x7734, - 0x11d2, - {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7} -}; -#endif -static GUID DInput_Wine_Mouse_GUID = { /* 9e573ed8-7734-11d2-8d4a-23903fb6bdf7 */ - 0x9e573ed8, - 0x7734, - 0x11d2, - {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7} -}; -static GUID DInput_Wine_Keyboard_GUID = { /* 0ab8648a-7735-11d2-8c73-71df54a96441 */ - 0x0ab8648a, - 0x7735, - 0x11d2, - {0x8c, 0x73, 0x71, 0xdf, 0x54, 0xa9, 0x64, 0x41} -}; - -/* FIXME: This is ugly and not thread safe :/ */ -static IDirectInputDevice2A* current_lock = NULL; - -/****************************************************************************** - * Various debugging tools +/* register a direct draw driver. We better not use malloc for we are in + * the ELF startup initialisation at this point. */ -static void _dump_cooperativelevel(DWORD dwFlags) { - int i; - const struct { - DWORD mask; - char *name; - } flags[] = { -#define FE(x) { x, #x}, - FE(DISCL_BACKGROUND) - FE(DISCL_EXCLUSIVE) - FE(DISCL_FOREGROUND) - FE(DISCL_NONEXCLUSIVE) -#undef FE - }; - for (i=0;i> 8); -} - -static void _dump_DIPROPHEADER(DIPROPHEADER *diph) { - DPRINTF(" - dwObj = 0x%08lx\n", diph->dwObj); - DPRINTF(" - dwHow = %s\n", - ((diph->dwHow == DIPH_DEVICE) ? "DIPH_DEVICE" : - ((diph->dwHow == DIPH_BYOFFSET) ? "DIPH_BYOFFSET" : - ((diph->dwHow == DIPH_BYID)) ? "DIPH_BYID" : "unknown"))); -} - -static void _dump_OBJECTINSTANCEA(DIDEVICEOBJECTINSTANCEA *ddoi) { - if (TRACE_ON(dinput)) { - DPRINTF(" - enumerating : 0x%08lx - %2ld - 0x%08lx - %s\n", - ddoi->guidType.Data1, ddoi->dwOfs, ddoi->dwType, ddoi->tszName); - } -} - -struct IDirectInputAImpl -{ - ICOM_VFIELD(IDirectInputA); - DWORD ref; -}; - -/* Conversion between internal data buffer and external data buffer */ -static void fill_DataFormat(void *out, void *in, DataFormat *df) { - int i; - char *in_c = (char *) in; - char *out_c = (char *) out; - - if (df->dt == NULL) { - /* This means that the app uses Wine's internal data format */ - memcpy(out, in, df->internal_format_size); - } else { - for (i = 0; i < df->size; i++) { - if (df->dt[i].offset_in >= 0) { - switch (df->dt[i].size) { - case 1: - TRACE("Copying (c) to %d from %d (value %d)\n", - df->dt[i].offset_out, df->dt[i].offset_in, *((char *) (in_c + df->dt[i].offset_in))); - *((char *) (out_c + df->dt[i].offset_out)) = *((char *) (in_c + df->dt[i].offset_in)); - break; - - case 2: - TRACE("Copying (s) to %d from %d (value %d)\n", - df->dt[i].offset_out, df->dt[i].offset_in, *((short *) (in_c + df->dt[i].offset_in))); - *((short *) (out_c + df->dt[i].offset_out)) = *((short *) (in_c + df->dt[i].offset_in)); - break; - - case 4: - TRACE("Copying (i) to %d from %d (value %d)\n", - df->dt[i].offset_out, df->dt[i].offset_in, *((int *) (in_c + df->dt[i].offset_in))); - *((int *) (out_c + df->dt[i].offset_out)) = *((int *) (in_c + df->dt[i].offset_in)); - break; - - default: - memcpy((out_c + df->dt[i].offset_out), (in_c + df->dt[i].offset_in), df->dt[i].size); - } - } else { - switch (df->dt[i].size) { - case 1: - TRACE("Copying (c) to %d default value %d\n", - df->dt[i].offset_out, df->dt[i].value); - *((char *) (out_c + df->dt[i].offset_out)) = (char) df->dt[i].value; - break; - - case 2: - TRACE("Copying (s) to %d default value %d\n", - df->dt[i].offset_out, df->dt[i].value); - *((short *) (out_c + df->dt[i].offset_out)) = (short) df->dt[i].value; - break; - - case 4: - TRACE("Copying (i) to %d default value %d\n", - df->dt[i].offset_out, df->dt[i].value); - *((int *) (out_c + df->dt[i].offset_out)) = (int) df->dt[i].value; - break; - - default: - memset((out_c + df->dt[i].offset_out), df->dt[i].size, 0); - } - } - } - } -} - -static DataFormat *create_DataFormat(DIDATAFORMAT *wine_format, LPCDIDATAFORMAT asked_format, int *offset) { - DataFormat *ret; - DataTransform *dt; - int i, j; - int same = 1; - int *done; - int index = 0; - - ret = (DataFormat *) HeapAlloc(GetProcessHeap(), 0, sizeof(DataFormat)); - - done = (int *) HeapAlloc(GetProcessHeap(), 0, sizeof(int) * asked_format->dwNumObjs); - memset(done, 0, sizeof(int) * asked_format->dwNumObjs); - - dt = (DataTransform *) HeapAlloc(GetProcessHeap(), 0, asked_format->dwNumObjs * sizeof(DataTransform)); - - TRACE("Creating DataTransorm : \n"); - - for (i = 0; i < wine_format->dwNumObjs; i++) { - offset[i] = -1; - - for (j = 0; j < asked_format->dwNumObjs; j++) { - if (done[j] == 1) - continue; - - if (((asked_format->rgodf[j].pguid == NULL) || (IsEqualGUID(wine_format->rgodf[i].pguid, asked_format->rgodf[j].pguid))) - && - (wine_format->rgodf[i].dwType & asked_format->rgodf[j].dwType)) { - - done[j] = 1; - - TRACE("Matching : \n"); - TRACE(" - Asked (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n", - j, debugstr_guid(asked_format->rgodf[j].pguid), - asked_format->rgodf[j].dwOfs, - DIDFT_GETTYPE(asked_format->rgodf[j].dwType), DIDFT_GETINSTANCE(asked_format->rgodf[j].dwType)); - - TRACE(" - Wine (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n", - j, debugstr_guid(wine_format->rgodf[i].pguid), - wine_format->rgodf[i].dwOfs, - DIDFT_GETTYPE(wine_format->rgodf[i].dwType), DIDFT_GETINSTANCE(wine_format->rgodf[i].dwType)); - - if (wine_format->rgodf[i].dwType & DIDFT_BUTTON) - dt[index].size = sizeof(BYTE); - else - dt[index].size = sizeof(DWORD); - dt[index].offset_in = wine_format ->rgodf[i].dwOfs; - dt[index].offset_out = asked_format->rgodf[j].dwOfs; - dt[index].value = 0; - index++; - - if (wine_format->rgodf[i].dwOfs != asked_format->rgodf[j].dwOfs) - same = 0; - - offset[i] = asked_format->rgodf[j].dwOfs; - break; - } - } - - if (j == asked_format->dwNumObjs) - same = 0; - } - - TRACE("Setting to default value :\n"); - for (j = 0; j < asked_format->dwNumObjs; j++) { - if (done[j] == 0) { - TRACE(" - Asked (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n", - j, debugstr_guid(asked_format->rgodf[j].pguid), - asked_format->rgodf[j].dwOfs, - DIDFT_GETTYPE(asked_format->rgodf[j].dwType), DIDFT_GETINSTANCE(asked_format->rgodf[j].dwType)); - - - if (asked_format->rgodf[j].dwType & DIDFT_BUTTON) - dt[index].size = sizeof(BYTE); - else - dt[index].size = sizeof(DWORD); - dt[index].offset_in = -1; - dt[index].offset_out = asked_format->rgodf[j].dwOfs; - dt[index].value = 0; - index++; - - same = 0; - } - } - - ret->internal_format_size = wine_format->dwDataSize; - ret->size = index; - if (same) { - ret->dt = NULL; - HeapFree(GetProcessHeap(), 0, dt); - } else { - ret->dt = dt; - } - - HeapFree(GetProcessHeap(), 0, done); - - return ret; + /* increase MAX_DDRAW_DRIVERS if the line below triggers */ + assert(nrof_dinput_devices <= MAX_WINE_DINPUT_DEVICES); } /****************************************************************************** @@ -486,16 +58,29 @@ HRESULT WINAPI DirectInputCreateEx( LPUNKNOWN punkOuter ) { IDirectInputAImpl* This; - HRESULT res; + TRACE("(0x%08lx,%04lx,%s,%p,%p)\n", (DWORD)hinst,dwVersion,debugstr_guid(riid),ppDI,punkOuter ); - This = (IDirectInputAImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputAImpl)); - This->ref = 1; - ICOM_VTBL(This) = &ddiavt; - res=IDirectInputA_QueryInterface((IUnknown *)This,riid,ppDI); - IDirectInputA_Release((IUnknown *)This); /* throw one reference away */ - return res; + if (IsEqualGUID(&IID_IDirectInputA,riid)) { + This = (IDirectInputAImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputAImpl)); + This->ref = 1; + ICOM_VTBL(This) = &ddiavt; + *ppDI = This; + + return DI_OK; + } + + if (IsEqualGUID(&IID_IDirectInput7A,riid)) { + This = (IDirectInputAImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputAImpl)); + This->ref = 1; + ICOM_VTBL(This) = (ICOM_VTABLE(IDirectInputA) *) &ddi7avt; + *ppDI = This; + + return DI_OK; + } + + return DIERR_OLDDIRECTINPUTVERSION; } /****************************************************************************** @@ -523,60 +108,17 @@ static HRESULT WINAPI IDirectInputAImpl_EnumDevices( { ICOM_THIS(IDirectInputAImpl,iface); DIDEVICEINSTANCEA devInstance; - int ret; + int i; TRACE("(this=%p,0x%04lx,%p,%p,%04lx)\n", This, dwDevType, lpCallback, pvRef, dwFlags); - devInstance.dwSize = sizeof(DIDEVICEINSTANCEA); - if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_KEYBOARD)) { - /* Return keyboard */ - devInstance.guidInstance = GUID_SysKeyboard;/* DInput's GUID */ - devInstance.guidProduct = DInput_Wine_Keyboard_GUID; /* Vendor's GUID */ - devInstance.dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_UNKNOWN << 8); - strcpy(devInstance.tszInstanceName, "Keyboard"); - strcpy(devInstance.tszProductName, "Wine Keyboard"); - - ret = lpCallback(&devInstance, pvRef); - TRACE("Keyboard registered\n"); - if (ret == DIENUM_STOP) - return 0; - } - - if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_MOUSE)) { - /* Return mouse */ - devInstance.guidInstance = GUID_SysMouse;/* DInput's GUID */ - devInstance.guidProduct = DInput_Wine_Mouse_GUID; /* Vendor's GUID */ - devInstance.dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_UNKNOWN << 8); - strcpy(devInstance.tszInstanceName, "Mouse"); - strcpy(devInstance.tszProductName, "Wine Mouse"); - - ret = lpCallback(&devInstance, pvRef); - TRACE("Mouse registered\n"); - if (ret == DIENUM_STOP) - return 0; - } - if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_JOYSTICK)) { - /* check whether we have a joystick */ -#ifdef HAVE_LINUX_22_JOYSTICK_API - if ( (access(JOYDEV,O_RDONLY)!=-1) || - (errno!=ENODEV && errno!=ENOENT) - ) { - /* Return joystick */ - devInstance.guidInstance = GUID_Joystick; - devInstance.guidProduct = DInput_Wine_Joystick_GUID; - /* we only support traditional joysticks for now */ - devInstance.dwDevType = DIDEVTYPE_JOYSTICK | DIDEVTYPEJOYSTICK_TRADITIONAL; - strcpy(devInstance.tszInstanceName, "Joystick"); - /* ioctl JSIOCGNAME(len) */ - strcpy(devInstance.tszProductName, "Wine Joystick"); - - ret = lpCallback(&devInstance,pvRef); - TRACE("Joystick registered\n"); - if (ret == DIENUM_STOP) - return 0; - } -#endif + for (i = 0; i < nrof_dinput_devices; i++) { + if (dinput_devices[i]->enum_device(dwDevType, dwFlags, &devInstance)) { + if (lpCallback(&devInstance,pvRef) == DIENUM_STOP) + return 0; + } } + return 0; } @@ -601,68 +143,22 @@ static HRESULT WINAPI IDirectInputAImpl_CreateDevice( LPUNKNOWN punk ) { ICOM_THIS(IDirectInputAImpl,iface); + HRESULT ret_value = DIERR_DEVICENOTREG; + int i; TRACE("(this=%p,%s,%p,%p)\n",This,debugstr_guid(rguid),pdev,punk); - if ((IsEqualGUID(&GUID_SysKeyboard,rguid)) || /* Generic Keyboard */ - (IsEqualGUID(&DInput_Wine_Keyboard_GUID,rguid))) { /* Wine Keyboard */ - SysKeyboardAImpl* newDevice; - newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysKeyboardAImpl)); - newDevice->ref = 1; - ICOM_VTBL(newDevice) = &SysKeyboardAvt; - memcpy(&(newDevice->guid),rguid,sizeof(*rguid)); - memset(newDevice->keystate,0,256); - *pdev=(IDirectInputDeviceA*)newDevice; - TRACE("Creating a Keyboard device (%p)\n", newDevice); - return DI_OK; - } - if ((IsEqualGUID(&GUID_SysMouse,rguid)) || /* Generic Mouse */ - (IsEqualGUID(&DInput_Wine_Mouse_GUID,rguid))) { /* Wine Mouse */ - SysMouseAImpl* newDevice; - int offset_array[5] = { - FIELD_OFFSET(Wine_InternalMouseData, lX), - FIELD_OFFSET(Wine_InternalMouseData, lY), - FIELD_OFFSET(Wine_InternalMouseData, rgbButtons) + 0, - FIELD_OFFSET(Wine_InternalMouseData, rgbButtons) + 1, - FIELD_OFFSET(Wine_InternalMouseData, rgbButtons) + 2 - }; - - newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysMouseAImpl)); - newDevice->ref = 1; - ICOM_VTBL(newDevice) = &SysMouseAvt; - InitializeCriticalSection(&(newDevice->crit)); - memcpy(&(newDevice->guid),rguid,sizeof(*rguid)); - *pdev=(IDirectInputDeviceA*)newDevice; + /* 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_device(This, rguid, NULL, pdev)) == DI_OK) + return DI_OK; - /* Per default, Wine uses its internal data format */ - newDevice->df = &Wine_InternalMouseFormat; - memcpy(newDevice->offset_array, offset_array, 5 * sizeof(int)); - newDevice->wine_df = (DataFormat *) HeapAlloc(GetProcessHeap(), 0, sizeof(DataFormat)); - newDevice->wine_df->size = 0; - newDevice->wine_df->internal_format_size = Wine_InternalMouseFormat.dwDataSize; - newDevice->wine_df->dt = NULL; - - TRACE("Creating a Mouse device (%p)\n", newDevice); - return DI_OK; + if (ret == DIERR_NOINTERFACE) + ret_value = DIERR_NOINTERFACE; } -#ifdef HAVE_LINUX_22_JOYSTICK_API - if ((IsEqualGUID(&GUID_Joystick,rguid)) || - (IsEqualGUID(&DInput_Wine_Joystick_GUID,rguid))) { - JoystickAImpl* newDevice; - newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(JoystickAImpl)); - newDevice->ref = 1; - ICOM_VTBL(newDevice) = &JoystickAvt; - newDevice->joyfd = -1; - newDevice->lMin = -32768; - newDevice->lMax = +32767; - memcpy(&(newDevice->guid),rguid,sizeof(*rguid)); - *pdev=(IDirectInputDeviceA*)newDevice; - TRACE("Creating a Joystick device (%p)\n", newDevice); - return DI_OK; - } -#endif - return E_FAIL; + return ret_value; } static HRESULT WINAPI IDirectInputAImpl_QueryInterface( @@ -709,6 +205,36 @@ static HRESULT WINAPI IDirectInputAImpl_RunControlPanel(LPDIRECTINPUTA iface, return DI_OK; } +static HRESULT WINAPI IDirectInput2AImpl_FindDevice(LPDIRECTINPUT2A iface, REFGUID rguid, + LPCSTR pszName, LPGUID pguidInstance) { + ICOM_THIS(IDirectInputAImpl,iface); + FIXME("(%p)->(%s, %s, %p): stub\n", This, debugstr_guid(rguid), pszName, pguidInstance); + + return DI_OK; +} + +static HRESULT WINAPI IDirectInput7AImpl_CreateDeviceEx(LPDIRECTINPUT7A iface, REFGUID rguid, + REFIID riid, LPVOID* pvOut, LPUNKNOWN lpUnknownOuter) +{ + ICOM_THIS(IDirectInputAImpl,iface); + HRESULT ret_value = DIERR_DEVICENOTREG; + int i; + + TRACE("(%p)->(%s, %s, %p, %p)\n", This, debugstr_guid(rguid), debugstr_guid(riid), pvOut, lpUnknownOuter); + + /* 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_device(This, rguid, riid, (LPDIRECTINPUTDEVICEA*) pvOut)) == DI_OK) + return DI_OK; + + if (ret == DIERR_NOINTERFACE) + ret_value = DIERR_NOINTERFACE; + } + + return ret_value; +} + static ICOM_VTABLE(IDirectInputA) ddiavt = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE @@ -722,1587 +248,26 @@ static ICOM_VTABLE(IDirectInputA) ddiavt = IDirectInputAImpl_Initialize }; -/****************************************************************************** - * IDirectInputDeviceA - */ - -static HRESULT WINAPI IDirectInputDevice2AImpl_SetDataFormat( - LPDIRECTINPUTDEVICE2A iface,LPCDIDATAFORMAT df -) { - /* - int i; - TRACE(dinput,"(this=%p,%p)\n",This,df); - - TRACE(dinput,"df.dwSize=%ld\n",df->dwSize); - TRACE(dinput,"(df.dwObjsize=%ld)\n",df->dwObjSize); - TRACE(dinput,"(df.dwFlags=0x%08lx)\n",df->dwFlags); - TRACE(dinput,"(df.dwDataSize=%ld)\n",df->dwDataSize); - TRACE(dinput,"(df.dwNumObjs=%ld)\n",df->dwNumObjs); - - for (i=0;idwNumObjs;i++) { - TRACE(dinput,"df.rgodf[%d].guid %s\n",i,debugstr_guid(df->rgodf[i].pguid)); - TRACE(dinput,"df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs); - TRACE(dinput,"dwType 0x%02lx,dwInstance %ld\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType)); - TRACE(dinput,"df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags); - } - */ - return 0; -} - -static HRESULT WINAPI IDirectInputDevice2AImpl_SetCooperativeLevel( - LPDIRECTINPUTDEVICE2A iface,HWND hwnd,DWORD dwflags -) { - ICOM_THIS(IDirectInputDevice2AImpl,iface); - TRACE("(this=%p,0x%08lx,0x%08lx)\n",This,(DWORD)hwnd,dwflags); - if (TRACE_ON(dinput)) - _dump_cooperativelevel(dwflags); - return 0; -} - -static HRESULT WINAPI IDirectInputDevice2AImpl_SetEventNotification( - LPDIRECTINPUTDEVICE2A iface,HANDLE hnd -) { - ICOM_THIS(IDirectInputDevice2AImpl,iface); - FIXME("(this=%p,0x%08lx): stub\n",This,(DWORD)hnd); - return 0; -} - -static ULONG WINAPI IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE2A iface) -{ - ICOM_THIS(IDirectInputDevice2AImpl,iface); - This->ref--; - if (This->ref) - return This->ref; - HeapFree(GetProcessHeap(),0,This); - return 0; -} - -static HRESULT WINAPI SysKeyboardAImpl_SetProperty( - LPDIRECTINPUTDEVICE2A iface,REFGUID rguid,LPCDIPROPHEADER ph -) -{ - ICOM_THIS(SysKeyboardAImpl,iface); - - TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(rguid),ph); - TRACE("(size=%ld,headersize=%ld,obj=%ld,how=%ld\n", - ph->dwSize,ph->dwHeaderSize,ph->dwObj,ph->dwHow); - if (!HIWORD(rguid)) { - switch ((DWORD)rguid) { - case (DWORD) DIPROP_BUFFERSIZE: { - LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph; - - TRACE("(buffersize=%ld)\n",pd->dwData); - break; - } - default: - WARN("Unknown type %ld\n",(DWORD)rguid); - break; - } - } - return 0; -} - -static HRESULT WINAPI SysKeyboardAImpl_GetDeviceState( - LPDIRECTINPUTDEVICE2A iface,DWORD len,LPVOID ptr -) -{ - return USER_Driver.pGetDIState(len, ptr)?DI_OK:E_FAIL; -} - -static HRESULT WINAPI SysKeyboardAImpl_GetDeviceData( - LPDIRECTINPUTDEVICE2A iface,DWORD dodsize,LPDIDEVICEOBJECTDATA dod, - LPDWORD entries,DWORD flags -) -{ - ICOM_THIS(SysKeyboardAImpl,iface); - HRESULT ret; - int i; - - TRACE("(this=%p,%ld,%p,%p(%ld)),0x%08lx)\n", - This,dodsize,dod,entries,entries?*entries:0,flags); - - ret=USER_Driver.pGetDIData( - This->keystate, dodsize, dod, entries, flags)?DI_OK:E_FAIL; - for (i=0;i<*entries;i++) { - dod[i].dwTimeStamp = GetTickCount(); - dod[i].dwSequence = evsequence++; - } - return ret; -} - -static HRESULT WINAPI SysKeyboardAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface) -{ - ICOM_THIS(SysKeyboardAImpl,iface); - - TRACE("(this=%p)\n",This); - - if (This->acquired == 0) { - KEYBOARD_CONFIG no_auto; - - /* Save the original config */ - USER_Driver.pGetKeyboardConfig(&(This->initial_config)); - - /* Now, remove auto-repeat */ - no_auto.auto_repeat = FALSE; - USER_Driver.pSetKeyboardConfig(&no_auto, WINE_KEYBOARD_CONFIG_AUTO_REPEAT); - - This->acquired = 1; - } - - return DI_OK; -} - -static HRESULT WINAPI SysKeyboardAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface) -{ - ICOM_THIS(SysKeyboardAImpl,iface); - TRACE("(this=%p)\n",This); - - if (This->acquired == 1) { - /* Restore the original configuration */ - USER_Driver.pSetKeyboardConfig(&(This->initial_config), 0xFFFFFFFF); - This->acquired = 0; - } else { - ERR("Unacquiring a not-acquired device !!!\n"); - } - - return DI_OK; -} - -/****************************************************************************** - * GetCapabilities : get the device capablitites - */ -static HRESULT WINAPI SysKeyboardAImpl_GetCapabilities( - LPDIRECTINPUTDEVICE2A iface, - LPDIDEVCAPS lpDIDevCaps) -{ - ICOM_THIS(SysMouseAImpl,iface); - - TRACE("(this=%p,%p)\n",This,lpDIDevCaps); - - if (lpDIDevCaps->dwSize == sizeof(DIDEVCAPS)) { - lpDIDevCaps->dwFlags = DIDC_ATTACHED; - lpDIDevCaps->dwDevType = DIDEVTYPE_KEYBOARD; - lpDIDevCaps->dwAxes = 0; - lpDIDevCaps->dwButtons = 0; - lpDIDevCaps->dwPOVs = 0; - lpDIDevCaps->dwFFSamplePeriod = 0; - lpDIDevCaps->dwFFMinTimeResolution = 0; - lpDIDevCaps->dwFirmwareRevision = 100; - lpDIDevCaps->dwHardwareRevision = 100; - lpDIDevCaps->dwFFDriverVersion = 0; - } else { - /* DirectX 3.0 */ - FIXME("DirectX 3.0 not supported....\n"); - } - - return DI_OK; -} - -static HRESULT WINAPI IDirectInputDevice2AImpl_QueryInterface( - LPDIRECTINPUTDEVICE2A iface,REFIID riid,LPVOID *ppobj -) -{ - ICOM_THIS(IDirectInputDevice2AImpl,iface); - - TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); - if (IsEqualGUID(&IID_IUnknown,riid)) { - IDirectInputDevice2_AddRef(iface); - *ppobj = This; - return 0; - } - if (IsEqualGUID(&IID_IDirectInputDeviceA,riid)) { - IDirectInputDevice2_AddRef(iface); - *ppobj = This; - return 0; - } - if (IsEqualGUID(&IID_IDirectInputDevice2A,riid)) { - IDirectInputDevice2_AddRef(iface); - *ppobj = This; - return 0; - } - TRACE("Unsupported interface !\n"); - return E_FAIL; -} - -static ULONG WINAPI IDirectInputDevice2AImpl_AddRef( - LPDIRECTINPUTDEVICE2A iface) -{ - ICOM_THIS(IDirectInputDevice2AImpl,iface); - return ++This->ref; -} - -static HRESULT WINAPI IDirectInputDevice2AImpl_EnumObjects( - LPDIRECTINPUTDEVICE2A iface, - LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback, - LPVOID lpvRef, - DWORD dwFlags) -{ - FIXME("(this=%p,%p,%p,%08lx): stub!\n", iface, lpCallback, lpvRef, dwFlags); - if (TRACE_ON(dinput)) { - DPRINTF(" - flags = "); - _dump_EnumObjects_flags(dwFlags); - DPRINTF("\n"); - } - - return DI_OK; -} - -static HRESULT WINAPI IDirectInputDevice2AImpl_GetProperty( - LPDIRECTINPUTDEVICE2A iface, - REFGUID rguid, - LPDIPROPHEADER pdiph) -{ - FIXME("(this=%p,%s,%p): stub!\n", - iface, debugstr_guid(rguid), pdiph); - - if (TRACE_ON(dinput)) - _dump_DIPROPHEADER(pdiph); - - return DI_OK; -} - -static HRESULT WINAPI IDirectInputDevice2AImpl_GetObjectInfo( - LPDIRECTINPUTDEVICE2A iface, - LPDIDEVICEOBJECTINSTANCEA pdidoi, - DWORD dwObj, - DWORD dwHow) -{ - FIXME("(this=%p,%p,%ld,0x%08lx): stub!\n", - iface, pdidoi, dwObj, dwHow); - - return DI_OK; -} - -static HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceInfo( - LPDIRECTINPUTDEVICE2A iface, - LPDIDEVICEINSTANCEA pdidi) -{ - FIXME("(this=%p,%p): stub!\n", - iface, pdidi); - - return DI_OK; -} - -static HRESULT WINAPI IDirectInputDevice2AImpl_RunControlPanel( - LPDIRECTINPUTDEVICE2A iface, - HWND hwndOwner, - DWORD dwFlags) -{ - FIXME("(this=%p,0x%08x,0x%08lx): stub!\n", - iface, hwndOwner, dwFlags); - - return DI_OK; -} - -static HRESULT WINAPI IDirectInputDevice2AImpl_Initialize( - LPDIRECTINPUTDEVICE2A iface, - HINSTANCE hinst, - DWORD dwVersion, - REFGUID rguid) -{ - FIXME("(this=%p,%d,%ld,%s): stub!\n", - iface, hinst, dwVersion, debugstr_guid(rguid)); - return DI_OK; -} - -/****************************************************************************** - * IDirectInputDevice2A - */ - -static HRESULT WINAPI IDirectInputDevice2AImpl_CreateEffect( - LPDIRECTINPUTDEVICE2A iface, - REFGUID rguid, - LPCDIEFFECT lpeff, - LPDIRECTINPUTEFFECT *ppdef, - LPUNKNOWN pUnkOuter) -{ - FIXME("(this=%p,%s,%p,%p,%p): stub!\n", - iface, debugstr_guid(rguid), lpeff, ppdef, pUnkOuter); - return DI_OK; -} - -static HRESULT WINAPI IDirectInputDevice2AImpl_EnumEffects( - LPDIRECTINPUTDEVICE2A iface, - LPDIENUMEFFECTSCALLBACKA lpCallback, - LPVOID lpvRef, - DWORD dwFlags) -{ - FIXME("(this=%p,%p,%p,0x%08lx): stub!\n", - iface, lpCallback, lpvRef, dwFlags); - - if (lpCallback) - lpCallback(NULL, lpvRef); - return DI_OK; -} - -static HRESULT WINAPI IDirectInputDevice2AImpl_GetEffectInfo( - LPDIRECTINPUTDEVICE2A iface, - LPDIEFFECTINFOA lpdei, - REFGUID rguid) -{ - FIXME("(this=%p,%p,%s): stub!\n", - iface, lpdei, debugstr_guid(rguid)); - return DI_OK; -} - -static HRESULT WINAPI IDirectInputDevice2AImpl_GetForceFeedbackState( - LPDIRECTINPUTDEVICE2A iface, - LPDWORD pdwOut) -{ - FIXME("(this=%p,%p): stub!\n", - iface, pdwOut); - return DI_OK; -} - -static HRESULT WINAPI IDirectInputDevice2AImpl_SendForceFeedbackCommand( - LPDIRECTINPUTDEVICE2A iface, - DWORD dwFlags) -{ - FIXME("(this=%p,0x%08lx): stub!\n", - iface, dwFlags); - return DI_OK; -} - -static HRESULT WINAPI IDirectInputDevice2AImpl_EnumCreatedEffectObjects( - LPDIRECTINPUTDEVICE2A iface, - LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback, - LPVOID lpvRef, - DWORD dwFlags) -{ - FIXME("(this=%p,%p,%p,0x%08lx): stub!\n", - iface, lpCallback, lpvRef, dwFlags); - if (lpCallback) - lpCallback(NULL, lpvRef); - return DI_OK; -} - -static HRESULT WINAPI IDirectInputDevice2AImpl_Escape( - LPDIRECTINPUTDEVICE2A iface, - LPDIEFFESCAPE lpDIEEsc) -{ - FIXME("(this=%p,%p): stub!\n", - iface, lpDIEEsc); - return DI_OK; -} - -static HRESULT WINAPI IDirectInputDevice2AImpl_Poll( - LPDIRECTINPUTDEVICE2A iface) -{ - FIXME("(this=%p): stub!\n", - iface); - return DI_OK; -} - -static HRESULT WINAPI IDirectInputDevice2AImpl_SendDeviceData( - LPDIRECTINPUTDEVICE2A iface, - DWORD cbObjectData, - LPDIDEVICEOBJECTDATA rgdod, - LPDWORD pdwInOut, - DWORD dwFlags) -{ - FIXME("(this=%p,0x%08lx,%p,%p,0x%08lx): stub!\n", - iface, cbObjectData, rgdod, pdwInOut, dwFlags); - - return DI_OK; -} - -/****************************************************************************** - * SysMouseA (DInput Mouse support) - */ - -/****************************************************************************** - * Release : release the mouse buffer. - */ -static ULONG WINAPI SysMouseAImpl_Release(LPDIRECTINPUTDEVICE2A iface) -{ - ICOM_THIS(SysMouseAImpl,iface); - - This->ref--; - if (This->ref) - return This->ref; - - /* Free the data queue */ - if (This->data_queue != NULL) - HeapFree(GetProcessHeap(),0,This->data_queue); - - /* Install the previous event handler (in case of releasing an acquired - mouse device) */ - if (This->prev_handler != NULL) - MOUSE_Enable(This->prev_handler); - DeleteCriticalSection(&(This->crit)); - - /* Free the DataFormat */ - if (This->df != &(Wine_InternalMouseFormat)) { - HeapFree(GetProcessHeap(), 0, This->df->rgodf); - HeapFree(GetProcessHeap(), 0, This->df); - } - - HeapFree(GetProcessHeap(),0,This); - return 0; -} - - -/****************************************************************************** - * SetCooperativeLevel : store the window in which we will do our - * grabbing. - */ -static HRESULT WINAPI SysMouseAImpl_SetCooperativeLevel( - LPDIRECTINPUTDEVICE2A iface,HWND hwnd,DWORD dwflags -) -{ - ICOM_THIS(SysMouseAImpl,iface); - - TRACE("(this=%p,0x%08lx,0x%08lx)\n",This,(DWORD)hwnd,dwflags); - - if (TRACE_ON(dinput)) - _dump_cooperativelevel(dwflags); - - /* Store the window which asks for the mouse */ - This->win = hwnd; - - return 0; -} - - -/****************************************************************************** - * SetDataFormat : the application can choose the format of the data - * the device driver sends back with GetDeviceState. - * - * For the moment, only the "standard" configuration (c_dfDIMouse) is supported - * in absolute and relative mode. - */ -static HRESULT WINAPI SysMouseAImpl_SetDataFormat( - LPDIRECTINPUTDEVICE2A iface,LPCDIDATAFORMAT df -) -{ - ICOM_THIS(SysMouseAImpl,iface); - int i; - - TRACE("(this=%p,%p)\n",This,df); - - TRACE("(df.dwSize=%ld)\n",df->dwSize); - TRACE("(df.dwObjsize=%ld)\n",df->dwObjSize); - TRACE("(df.dwFlags=0x%08lx)\n",df->dwFlags); - TRACE("(df.dwDataSize=%ld)\n",df->dwDataSize); - TRACE("(df.dwNumObjs=%ld)\n",df->dwNumObjs); - - for (i=0;idwNumObjs;i++) { - - TRACE("df.rgodf[%d].guid %s (%p)\n",i, debugstr_guid(df->rgodf[i].pguid), df->rgodf[i].pguid); - TRACE("df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs); - TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType)); - TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags); - } - - /* Check if the mouse is in absolute or relative mode */ - if (df->dwFlags == DIDF_ABSAXIS) - This->absolute = 1; - else if (df->dwFlags == DIDF_RELAXIS) - This->absolute = 0; - else - ERR("Neither absolute nor relative flag set."); - - /* Store the new data format */ - This->df = HeapAlloc(GetProcessHeap(),0,df->dwSize); - memcpy(This->df, df, df->dwSize); - This->df->rgodf = HeapAlloc(GetProcessHeap(),0,df->dwNumObjs*df->dwObjSize); - memcpy(This->df->rgodf,df->rgodf,df->dwNumObjs*df->dwObjSize); - - /* Prepare all the data-conversion filters */ - This->wine_df = create_DataFormat(&(Wine_InternalMouseFormat), df, This->offset_array); - - return 0; -} - -#define GEN_EVENT(offset,data,xtime,seq) \ -{ \ - /* If queue_len > 0, queuing is requested -> TRACE the event queued */ \ - if (This->queue_len > 0) { \ - TRACE(" queueing %d at offset %d (queue pos %d / size %d)\n", \ - (int) (data), (int) (offset), \ - (int) (This->queue_pos), (int) (This->queue_len)); \ - \ - if ((offset >= 0) && (This->queue_pos < This->queue_len)) { \ - This->data_queue[This->queue_pos].dwOfs = offset; \ - This->data_queue[This->queue_pos].dwData = data; \ - This->data_queue[This->queue_pos].dwTimeStamp = xtime; \ - This->data_queue[This->queue_pos].dwSequence = seq; \ - This->queue_pos++; \ - } \ - } \ -} - - -/* Our private mouse event handler */ -static void WINAPI dinput_mouse_event( DWORD dwFlags, DWORD dx, DWORD dy, - DWORD cButtons, DWORD dwExtraInfo ) -{ - long posX = -1, posY = -1; - DWORD keyState, xtime, extra; - SysMouseAImpl* This = (SysMouseAImpl*) current_lock; - - EnterCriticalSection(&(This->crit)); - /* Mouse moved -> send event if asked */ - if (This->hEvent) - SetEvent(This->hEvent); - - if ( !IsBadReadPtr( (LPVOID)dwExtraInfo, sizeof(WINE_MOUSEEVENT) ) - && ((WINE_MOUSEEVENT *)dwExtraInfo)->magic == WINE_MOUSEEVENT_MAGIC ) { - WINE_MOUSEEVENT *wme = (WINE_MOUSEEVENT *)dwExtraInfo; - keyState = wme->keyState; - xtime = wme->time; - extra = (DWORD)wme->hWnd; - - if (dwFlags & MOUSEEVENTF_MOVE) { - if (dwFlags & MOUSEEVENTF_ABSOLUTE) { - posX = (dx * GetSystemMetrics(SM_CXSCREEN)) >> 16; - posY = (dy * GetSystemMetrics(SM_CYSCREEN)) >> 16; - - if (This->absolute) { - if (posX != This->prevX) - GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], posX, xtime, 0); - if (posY != This->prevY) - GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], posY, xtime, 0); - } else { - /* Now, warp handling */ - if ((This->need_warp == WARP_STARTED) && - (posX == This->win_centerX) && (posX == This->win_centerX)) { - /* Warp has been done... */ - This->need_warp = WARP_DONE; - LeaveCriticalSection(&(This->crit)); - return; - } - - /* Relative mouse input with absolute mouse event : the real fun starts here... */ - if ((This->need_warp == WARP_NEEDED) || - (This->need_warp == WARP_STARTED)) { - if (posX != This->prevX) - GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], posX - This->prevX, xtime, evsequence++); - if (posY != This->prevY) - GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], posY - This->prevY, xtime, evsequence++); - } else { - /* This is the first time the event handler has been called after a - GetData of GetState. */ - if (posX != This->win_centerX) { - GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], posX - This->win_centerX, xtime, evsequence++); - This->need_warp = WARP_NEEDED; - } - - if (posY != This->win_centerY) { - GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], posY - This->win_centerY, xtime, evsequence++); - This->need_warp = WARP_NEEDED; - } - } - } - - This->prevX = posX; - This->prevY = posY; - - if (This->absolute) { - This->m_state.lX = posX; - This->m_state.lY = posY; - } else { - This->m_state.lX = posX - This->win_centerX; - This->m_state.lY = posY - This->win_centerY; - } - } else { - /* Mouse reporting is in relative mode */ - posX = (long) dx; - posY = (long) dy; - - if (This->absolute) { - long aposX, aposY; - - aposX = This->m_state.lX + posX; - if (aposX < 0) - aposX = 0; - if (aposX >= GetSystemMetrics(SM_CXSCREEN)) - aposX = GetSystemMetrics(SM_CXSCREEN); - - aposY = This->m_state.lY + posY; - if (aposY < 0) - aposY = 0; - if (aposY >= GetSystemMetrics(SM_CYSCREEN)) - aposY = GetSystemMetrics(SM_CYSCREEN); - - if (posX != 0) - GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], aposX, xtime, evsequence++); - if (posY != 0) - GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], aposY, xtime, evsequence++); - - This->m_state.lX = aposX; - This->m_state.lY = aposY; - } else { - if (posX != 0) - GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], posX, xtime, evsequence++); - if (posY != 0) - GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], posY, xtime, evsequence++); - - This->m_state.lX = posX; - This->m_state.lY = posY; - } - } - } - } else { - ERR("Mouse event not supported...\n"); - LeaveCriticalSection(&(This->crit)); - return ; - } - - if (TRACE_ON(dinput)) { - if (dwFlags & MOUSEEVENTF_MOVE) - TRACE(" %ld %ld (%s)", posX, posY, - (dwFlags & MOUSEEVENTF_ABSOLUTE ? "abs" : "rel")); - - if ( dwFlags & MOUSEEVENTF_LEFTDOWN ) DPRINTF(" LD "); - if ( dwFlags & MOUSEEVENTF_LEFTUP ) DPRINTF(" LU "); - - if ( dwFlags & MOUSEEVENTF_RIGHTDOWN ) DPRINTF(" RD "); - if ( dwFlags & MOUSEEVENTF_RIGHTUP ) DPRINTF(" RU "); - - if ( dwFlags & MOUSEEVENTF_MIDDLEDOWN ) DPRINTF(" MD "); - if ( dwFlags & MOUSEEVENTF_MIDDLEUP ) DPRINTF(" MU "); - - if (!(This->absolute)) DPRINTF(" W=%d ", This->need_warp); - - DPRINTF("\n"); - } - - - if ( dwFlags & MOUSEEVENTF_LEFTDOWN ) { - GEN_EVENT(This->offset_array[WINE_MOUSE_L_POSITION], 0xFF, xtime, evsequence++); - This->m_state.rgbButtons[0] = 0xFF; - } - if ( dwFlags & MOUSEEVENTF_LEFTUP ) { - GEN_EVENT(This->offset_array[WINE_MOUSE_L_POSITION], 0x00, xtime, evsequence++); - This->m_state.rgbButtons[0] = 0x00; - } - if ( dwFlags & MOUSEEVENTF_RIGHTDOWN ) { - GEN_EVENT(This->offset_array[WINE_MOUSE_R_POSITION], 0xFF, xtime, evsequence++); - This->m_state.rgbButtons[1] = 0xFF; - } - if ( dwFlags & MOUSEEVENTF_RIGHTUP ) { - GEN_EVENT(This->offset_array[WINE_MOUSE_R_POSITION], 0x00, xtime, evsequence++); - This->m_state.rgbButtons[1] = 0x00; - } - if ( dwFlags & MOUSEEVENTF_MIDDLEDOWN ) { - GEN_EVENT(This->offset_array[WINE_MOUSE_M_POSITION], 0xFF, xtime, evsequence++); - This->m_state.rgbButtons[2] = 0xFF; - } - if ( dwFlags & MOUSEEVENTF_MIDDLEUP ) { - GEN_EVENT(This->offset_array[WINE_MOUSE_M_POSITION], 0x00, xtime, evsequence++); - This->m_state.rgbButtons[2] = 0x00; - } - - TRACE("(X: %ld - Y: %ld L: %02x M: %02x R: %02x)\n", - This->m_state.lX, This->m_state.lY, - This->m_state.rgbButtons[0], This->m_state.rgbButtons[2], This->m_state.rgbButtons[1]); - - LeaveCriticalSection(&(This->crit)); -} - - -/****************************************************************************** - * Acquire : gets exclusive control of the mouse - */ -static HRESULT WINAPI SysMouseAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface) -{ - ICOM_THIS(SysMouseAImpl,iface); - RECT rect; - - TRACE("(this=%p)\n",This); - - if (This->acquired == 0) { - POINT point; - - /* This stores the current mouse handler. */ - This->prev_handler = mouse_event; - - /* Store (in a global variable) the current lock */ - current_lock = (IDirectInputDevice2A*)This; - - /* Init the mouse state */ - if (This->absolute) { - This->m_state.lX = PosX; - This->m_state.lY = PosY; - - This->prevX = PosX; - This->prevY = PosY; - } else { - This->m_state.lX = 0; - This->m_state.lY = 0; - } - This->m_state.rgbButtons[0] = (MouseButtonsStates[0] ? 0xFF : 0x00); - This->m_state.rgbButtons[1] = (MouseButtonsStates[1] ? 0xFF : 0x00); - This->m_state.rgbButtons[2] = (MouseButtonsStates[2] ? 0xFF : 0x00); - - /* Install our own mouse event handler */ - MOUSE_Enable(dinput_mouse_event); - - /* Get the window dimension and find the center */ - GetWindowRect(This->win, &rect); - This->win_centerX = (rect.right - rect.left) / 2; - This->win_centerY = (rect.bottom - rect.top ) / 2; - - /* Warp the mouse to the center of the window */ - if (This->absolute == 0) { - TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY); - point.x = This->win_centerX; - point.y = This->win_centerY; - MapWindowPoints(This->win, HWND_DESKTOP, &point, 1); - USER_Driver.pMoveCursor( point.x, point.y ); - This->need_warp = WARP_STARTED; - } - - This->acquired = 1; - } - return DI_OK; -} - -/****************************************************************************** - * Unacquire : frees the mouse - */ -static HRESULT WINAPI SysMouseAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface) -{ - ICOM_THIS(SysMouseAImpl,iface); - - TRACE("(this=%p)\n",This); - - if (This->acquired) - { - /* Reinstall previous mouse event handler */ - MOUSE_Enable(This->prev_handler); - This->prev_handler = NULL; - - /* No more locks */ - current_lock = NULL; - - /* Unacquire device */ - This->acquired = 0; - } - else - ERR("Unacquiring a not-acquired device !!!\n"); - - return DI_OK; -} - -/****************************************************************************** - * GetDeviceState : returns the "state" of the mouse. - * - * For the moment, only the "standard" return structure (DIMOUSESTATE) is - * supported. - */ -static HRESULT WINAPI SysMouseAImpl_GetDeviceState( - LPDIRECTINPUTDEVICE2A iface,DWORD len,LPVOID ptr -) { - ICOM_THIS(SysMouseAImpl,iface); - - EnterCriticalSection(&(This->crit)); - TRACE("(this=%p,0x%08lx,%p): \n",This,len,ptr); - - /* Copy the current mouse state */ - fill_DataFormat(ptr, &(This->m_state), This->wine_df); - - /* Initialize the buffer when in relative mode */ - if (This->absolute == 0) { - This->m_state.lX = 0; - This->m_state.lY = 0; - } - - /* Check if we need to do a mouse warping */ - if (This->need_warp == WARP_NEEDED) { - POINT point; - - TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY); - point.x = This->win_centerX; - point.y = This->win_centerY; - MapWindowPoints(This->win, HWND_DESKTOP, &point, 1); - USER_Driver.pMoveCursor( point.x, point.y ); - - This->need_warp = WARP_STARTED; - } - - LeaveCriticalSection(&(This->crit)); - - TRACE("(X: %ld - Y: %ld L: %02x M: %02x R: %02x)\n", - This->m_state.lX, This->m_state.lY, - This->m_state.rgbButtons[0], This->m_state.rgbButtons[2], This->m_state.rgbButtons[1]); - - return 0; -} - -/****************************************************************************** - * GetDeviceState : gets buffered input data. - */ -static HRESULT WINAPI SysMouseAImpl_GetDeviceData(LPDIRECTINPUTDEVICE2A iface, - DWORD dodsize, - LPDIDEVICEOBJECTDATA dod, - LPDWORD entries, - DWORD flags -) { - ICOM_THIS(SysMouseAImpl,iface); - - EnterCriticalSection(&(This->crit)); - TRACE("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx)\n",This,dodsize,*entries,flags); - - if (flags & DIGDD_PEEK) - FIXME("DIGDD_PEEK\n"); - - if (dod == NULL) { - *entries = This->queue_pos; - This->queue_pos = 0; - } else { - /* Check for buffer overflow */ - if (This->queue_pos > *entries) { - WARN("Buffer overflow not handled properly yet...\n"); - This->queue_pos = *entries; - } - if (dodsize != sizeof(DIDEVICEOBJECTDATA)) { - ERR("Wrong structure size !\n"); - LeaveCriticalSection(&(This->crit)); - return DIERR_INVALIDPARAM; - } - - if (This->queue_pos) - TRACE("Application retrieving %d event(s).\n", This->queue_pos); - - /* Copy the buffered data into the application queue */ - memcpy(dod, This->data_queue, This->queue_pos * dodsize); - *entries = This->queue_pos; - - /* Reset the event queue */ - This->queue_pos = 0; - } - LeaveCriticalSection(&(This->crit)); - - /* Check if we need to do a mouse warping */ - if (This->need_warp == WARP_NEEDED) { - POINT point; - - TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY); - point.x = This->win_centerX; - point.y = This->win_centerY; - MapWindowPoints(This->win, HWND_DESKTOP, &point, 1); - - USER_Driver.pMoveCursor( point.x, point.y ); - - This->need_warp = WARP_STARTED; - } - return 0; -} - -/****************************************************************************** - * SetProperty : change input device properties - */ -static HRESULT WINAPI SysMouseAImpl_SetProperty(LPDIRECTINPUTDEVICE2A iface, - REFGUID rguid, - LPCDIPROPHEADER ph) -{ - ICOM_THIS(SysMouseAImpl,iface); - - TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(rguid),ph); - - if (!HIWORD(rguid)) { - switch ((DWORD)rguid) { - case (DWORD) DIPROP_BUFFERSIZE: { - LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph; - - TRACE("buffersize = %ld\n",pd->dwData); - - This->data_queue = (LPDIDEVICEOBJECTDATA)HeapAlloc(GetProcessHeap(),0, - pd->dwData * sizeof(DIDEVICEOBJECTDATA)); - This->queue_pos = 0; - This->queue_len = pd->dwData; - break; - } - case (DWORD) DIPROP_AXISMODE: { - LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph; - This->absolute = !(pd->dwData); - TRACE("absolute mode: %d\n", This->absolute); - break; - } - default: - FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,debugstr_guid(rguid)); - break; - } - } - - return 0; -} - -/****************************************************************************** - * GetProperty : get input device properties - */ -static HRESULT WINAPI SysMouseAImpl_GetProperty(LPDIRECTINPUTDEVICE2A iface, - REFGUID rguid, - LPDIPROPHEADER pdiph) -{ - ICOM_THIS(SysMouseAImpl,iface); - - TRACE("(this=%p,%s,%p): stub!\n", - iface, debugstr_guid(rguid), pdiph); - - if (TRACE_ON(dinput)) - _dump_DIPROPHEADER(pdiph); - - if (!HIWORD(rguid)) { - switch ((DWORD)rguid) { - case (DWORD) DIPROP_BUFFERSIZE: { - LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph; - - TRACE(" return buffersize = %d\n",This->queue_len); - pd->dwData = This->queue_len; - break; - } - - case (DWORD) DIPROP_RANGE: { - LPDIPROPRANGE pr = (LPDIPROPRANGE) pdiph; - - if ((pdiph->dwHow == DIPH_BYID) && - ((pdiph->dwObj == (DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS)) || - (pdiph->dwObj == (DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS)))) { - /* Querying the range of either the X or the Y axis. As I do - not know the range, do as if the range where - unrestricted...*/ - pr->lMin = DIPROPRANGE_NOMIN; - pr->lMax = DIPROPRANGE_NOMAX; - } - - break; - } - - default: - FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,debugstr_guid(rguid)); - break; - } - } - - - return DI_OK; -} - - - -/****************************************************************************** - * SetEventNotification : specifies event to be sent on state change - */ -static HRESULT WINAPI SysMouseAImpl_SetEventNotification(LPDIRECTINPUTDEVICE2A iface, - HANDLE hnd) { - ICOM_THIS(SysMouseAImpl,iface); - - TRACE("(this=%p,0x%08lx)\n",This,(DWORD)hnd); - - This->hEvent = hnd; - - return DI_OK; -} - -/****************************************************************************** - * GetCapabilities : get the device capablitites - */ -static HRESULT WINAPI SysMouseAImpl_GetCapabilities( - LPDIRECTINPUTDEVICE2A iface, - LPDIDEVCAPS lpDIDevCaps) -{ - ICOM_THIS(SysMouseAImpl,iface); - - TRACE("(this=%p,%p)\n",This,lpDIDevCaps); - - if (lpDIDevCaps->dwSize == sizeof(DIDEVCAPS)) { - lpDIDevCaps->dwFlags = DIDC_ATTACHED; - lpDIDevCaps->dwDevType = DIDEVTYPE_MOUSE; - lpDIDevCaps->dwAxes = 2; - lpDIDevCaps->dwButtons = 3; - lpDIDevCaps->dwPOVs = 0; - lpDIDevCaps->dwFFSamplePeriod = 0; - lpDIDevCaps->dwFFMinTimeResolution = 0; - lpDIDevCaps->dwFirmwareRevision = 100; - lpDIDevCaps->dwHardwareRevision = 100; - lpDIDevCaps->dwFFDriverVersion = 0; - } else { - /* DirectX 3.0 */ - FIXME("DirectX 3.0 not supported....\n"); - } - - return DI_OK; -} - - -/****************************************************************************** - * EnumObjects : enumerate the different buttons and axis... - */ -static HRESULT WINAPI SysMouseAImpl_EnumObjects( - LPDIRECTINPUTDEVICE2A iface, - LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback, - LPVOID lpvRef, - DWORD dwFlags) -{ - ICOM_THIS(SysMouseAImpl,iface); - DIDEVICEOBJECTINSTANCEA ddoi; - - TRACE("(this=%p,%p,%p,%08lx)\n", This, lpCallback, lpvRef, dwFlags); - if (TRACE_ON(dinput)) { - DPRINTF(" - flags = "); - _dump_EnumObjects_flags(dwFlags); - DPRINTF("\n"); - } - - /* Only the fields till dwFFMaxForce are relevant */ - ddoi.dwSize = FIELD_OFFSET(DIDEVICEOBJECTINSTANCEA, dwFFMaxForce); - - /* In a mouse, we have : two relative axis and three buttons */ - if ((dwFlags == DIDFT_ALL) || - (dwFlags & DIDFT_AXIS)) { - /* X axis */ - ddoi.guidType = GUID_XAxis; - ddoi.dwOfs = This->offset_array[WINE_MOUSE_X_POSITION]; - ddoi.dwType = DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS; - strcpy(ddoi.tszName, "X-Axis"); - _dump_OBJECTINSTANCEA(&ddoi); - if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK; - - /* Y axis */ - ddoi.guidType = GUID_YAxis; - ddoi.dwOfs = This->offset_array[WINE_MOUSE_Y_POSITION]; - ddoi.dwType = DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS; - strcpy(ddoi.tszName, "Y-Axis"); - _dump_OBJECTINSTANCEA(&ddoi); - if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK; - } - - if ((dwFlags == DIDFT_ALL) || - (dwFlags & DIDFT_BUTTON)) { - ddoi.guidType = GUID_Button; - - /* Left button */ - ddoi.dwOfs = This->offset_array[WINE_MOUSE_L_POSITION]; - ddoi.dwType = DIDFT_MAKEINSTANCE(WINE_MOUSE_L_BUTTON_INSTANCE) | DIDFT_PSHBUTTON; - strcpy(ddoi.tszName, "Left-Button"); - _dump_OBJECTINSTANCEA(&ddoi); - if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK; - - /* Right button */ - ddoi.dwOfs = This->offset_array[WINE_MOUSE_R_POSITION]; - ddoi.dwType = DIDFT_MAKEINSTANCE(WINE_MOUSE_R_BUTTON_INSTANCE) | DIDFT_PSHBUTTON; - strcpy(ddoi.tszName, "Right-Button"); - _dump_OBJECTINSTANCEA(&ddoi); - if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK; - - /* Middle button */ - ddoi.dwOfs = This->offset_array[WINE_MOUSE_M_POSITION]; - ddoi.dwType = DIDFT_MAKEINSTANCE(WINE_MOUSE_M_BUTTON_INSTANCE) | DIDFT_PSHBUTTON; - strcpy(ddoi.tszName, "Middle-Button"); - _dump_OBJECTINSTANCEA(&ddoi); - if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK; - } - - return DI_OK; -} - - - -#ifdef HAVE_LINUX_22_JOYSTICK_API -/****************************************************************************** - * Joystick - */ -static ULONG WINAPI JoystickAImpl_Release(LPDIRECTINPUTDEVICE2A iface) -{ - ICOM_THIS(JoystickAImpl,iface); - - This->ref--; - if (This->ref) - return This->ref; - - /* Free the data queue */ - if (This->data_queue != NULL) - HeapFree(GetProcessHeap(),0,This->data_queue); - - /* Free the DataFormat */ - HeapFree(GetProcessHeap(), 0, This->df); - - HeapFree(GetProcessHeap(),0,This); - return 0; -} - -/****************************************************************************** - * SetDataFormat : the application can choose the format of the data - * the device driver sends back with GetDeviceState. - */ -static HRESULT WINAPI JoystickAImpl_SetDataFormat( - LPDIRECTINPUTDEVICE2A iface,LPCDIDATAFORMAT df -) -{ - ICOM_THIS(JoystickAImpl,iface); - int i; - - TRACE("(this=%p,%p)\n",This,df); - - TRACE("(df.dwSize=%ld)\n",df->dwSize); - TRACE("(df.dwObjsize=%ld)\n",df->dwObjSize); - TRACE("(df.dwFlags=0x%08lx)\n",df->dwFlags); - TRACE("(df.dwDataSize=%ld)\n",df->dwDataSize); - TRACE("(df.dwNumObjs=%ld)\n",df->dwNumObjs); - - for (i=0;idwNumObjs;i++) { - TRACE("df.rgodf[%d].guid %s (%p)\n",i,debugstr_guid(df->rgodf[i].pguid), df->rgodf[i].pguid); - TRACE("df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs); - TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType)); - TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags); - } - - /* Store the new data format */ - This->df = HeapAlloc(GetProcessHeap(),0,df->dwSize); - memcpy(This->df, df, df->dwSize); - This->df->rgodf = HeapAlloc(GetProcessHeap(),0,df->dwNumObjs*df->dwObjSize); - memcpy(This->df->rgodf,df->rgodf,df->dwNumObjs*df->dwObjSize); - - return 0; -} - -/****************************************************************************** - * Acquire : gets exclusive control of the joystick - */ -static HRESULT WINAPI JoystickAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface) -{ - ICOM_THIS(JoystickAImpl,iface); - - TRACE("(this=%p)\n",This); - if (This->joyfd!=-1) - return 0; - This->joyfd=open(JOYDEV,O_RDONLY); - if (This->joyfd==-1) - return DIERR_NOTFOUND; - return 0; -} - -/****************************************************************************** - * Unacquire : frees the joystick - */ -static HRESULT WINAPI JoystickAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface) -{ - ICOM_THIS(JoystickAImpl,iface); - - TRACE("(this=%p)\n",This); - if (This->joyfd!=-1) { - close(This->joyfd); - This->joyfd = -1; - } - return DI_OK; -} - -#define map_axis(val) ((val+32768)*(This->lMax-This->lMin)/65536+This->lMin) - -static void joy_polldev(JoystickAImpl *This) { - struct timeval tv; - fd_set readfds; - struct js_event jse; - - if (This->joyfd==-1) - return; - while (1) { - memset(&tv,0,sizeof(tv)); - FD_ZERO(&readfds);FD_SET(This->joyfd,&readfds); - if (1>select(This->joyfd+1,&readfds,NULL,NULL,&tv)) - return; - /* we have one event, so we can read */ - if (sizeof(jse)!=read(This->joyfd,&jse,sizeof(jse))) { - return; - } - TRACE("js_event: type 0x%x, number %d, value %d\n",jse.type,jse.number,jse.value); - if (jse.type & JS_EVENT_BUTTON) { - GEN_EVENT(DIJOFS_BUTTON(jse.number),jse.value?0x80:0x00,jse.time,evsequence++); - This->js.rgbButtons[jse.number] = jse.value?0x80:0x00; - } - if (jse.type & JS_EVENT_AXIS) { - switch (jse.number) { - case 0: - GEN_EVENT(jse.number*4,jse.value,jse.time,evsequence++); - This->js.lX = map_axis(jse.value); - break; - case 1: - GEN_EVENT(jse.number*4,jse.value,jse.time,evsequence++); - This->js.lY = map_axis(jse.value); - break; - case 2: - GEN_EVENT(jse.number*4,jse.value,jse.time,evsequence++); - This->js.lZ = map_axis(jse.value); - break; - default: - FIXME("more then 3 axes (%d) not handled!\n",jse.number); - break; - } - } - } -} - -/****************************************************************************** - * GetDeviceState : returns the "state" of the joystick. - * - */ -static HRESULT WINAPI JoystickAImpl_GetDeviceState( - LPDIRECTINPUTDEVICE2A iface,DWORD len,LPVOID ptr -) { - ICOM_THIS(JoystickAImpl,iface); - - joy_polldev(This); - TRACE("(this=%p,0x%08lx,%p)\n",This,len,ptr); - if (len != sizeof(DIJOYSTATE)) { - FIXME("len %ld is not sizeof(DIJOYSTATE), unsupported format.\n",len); - } - memcpy(ptr,&(This->js),len); - This->queue_pos = 0; - return 0; -} - -/****************************************************************************** - * GetDeviceData : gets buffered input data. - */ -static HRESULT WINAPI JoystickAImpl_GetDeviceData(LPDIRECTINPUTDEVICE2A iface, - DWORD dodsize, - LPDIDEVICEOBJECTDATA dod, - LPDWORD entries, - DWORD flags -) { - ICOM_THIS(JoystickAImpl,iface); - - FIXME("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx),STUB!\n",This,dodsize,*entries,flags); - - joy_polldev(This); - if (flags & DIGDD_PEEK) - FIXME("DIGDD_PEEK\n"); - - if (dod == NULL) { - } else { - } - return 0; -} - -/****************************************************************************** - * SetProperty : change input device properties - */ -static HRESULT WINAPI JoystickAImpl_SetProperty(LPDIRECTINPUTDEVICE2A iface, - REFGUID rguid, - LPCDIPROPHEADER ph) -{ - ICOM_THIS(JoystickAImpl,iface); - - FIXME("(this=%p,%s,%p)\n",This,debugstr_guid(rguid),ph); - FIXME("ph.dwSize = %ld, ph.dwHeaderSize =%ld, ph.dwObj = %ld, ph.dwHow= %ld\n",ph->dwSize, ph->dwHeaderSize,ph->dwObj,ph->dwHow); - - if (!HIWORD(rguid)) { - switch ((DWORD)rguid) { - case (DWORD) DIPROP_BUFFERSIZE: { - LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph; - - FIXME("buffersize = %ld\n",pd->dwData); - break; - } - case (DWORD)DIPROP_RANGE: { - LPCDIPROPRANGE pr = (LPCDIPROPRANGE)ph; - - FIXME("proprange(%ld,%ld)\n",pr->lMin,pr->lMax); - This->lMin = pr->lMin; - This->lMax = pr->lMax; - break; - } - case (DWORD)DIPROP_DEADZONE: { - LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph; - - FIXME("deadzone(%ld)\n",pd->dwData); - This->deadzone = pd->dwData; - break; - } - default: - FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,debugstr_guid(rguid)); - break; - } - } - return 0; -} - -/****************************************************************************** - * SetEventNotification : specifies event to be sent on state change - */ -static HRESULT WINAPI JoystickAImpl_SetEventNotification( - LPDIRECTINPUTDEVICE2A iface, HANDLE hnd -) { - ICOM_THIS(JoystickAImpl,iface); - - TRACE("(this=%p,0x%08lx)\n",This,(DWORD)hnd); - This->hEvent = hnd; - return DI_OK; -} - -static HRESULT WINAPI JoystickAImpl_GetCapabilities( - LPDIRECTINPUTDEVICE2A iface, - LPDIDEVCAPS lpDIDevCaps) -{ - ICOM_THIS(JoystickAImpl,iface); - BYTE axes,buttons; - int xfd = This->joyfd; - - TRACE("%p->(%p)\n",iface,lpDIDevCaps); - if (xfd==-1) - xfd = open(JOYDEV,O_RDONLY); - lpDIDevCaps->dwFlags = DIDC_ATTACHED; - lpDIDevCaps->dwDevType = DIDEVTYPE_JOYSTICK; -#ifdef JSIOCGAXES - if (-1==ioctl(xfd,JSIOCGAXES,&axes)) - axes = 2; - lpDIDevCaps->dwAxes = axes; -#endif -#ifdef JSIOCGBUTTONS - if (-1==ioctl(xfd,JSIOCGAXES,&buttons)) - buttons = 2; - lpDIDevCaps->dwButtons = buttons; -#endif - if (xfd!=This->joyfd) - close(xfd); - return DI_OK; -} -static HRESULT WINAPI JoystickAImpl_Poll(LPDIRECTINPUTDEVICE2A iface) { - ICOM_THIS(JoystickAImpl,iface); - TRACE("(),stub!\n"); - - joy_polldev(This); - return DI_OK; -} - -/****************************************************************************** - * EnumObjects : enumerate the different buttons and axis... - */ -static HRESULT WINAPI JoystickAImpl_EnumObjects( - LPDIRECTINPUTDEVICE2A iface, - LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback, - LPVOID lpvRef, - DWORD dwFlags) -{ - ICOM_THIS(JoystickAImpl,iface); - DIDEVICEOBJECTINSTANCEA ddoi; - int xfd = This->joyfd; - - TRACE("(this=%p,%p,%p,%08lx)\n", This, lpCallback, lpvRef, dwFlags); - if (TRACE_ON(dinput)) { - DPRINTF(" - flags = "); - _dump_EnumObjects_flags(dwFlags); - DPRINTF("\n"); - } - - /* Only the fields till dwFFMaxForce are relevant */ - ddoi.dwSize = FIELD_OFFSET(DIDEVICEOBJECTINSTANCEA, dwFFMaxForce); - - /* For the joystick, do as is done in the GetCapabilities function */ - if ((dwFlags == DIDFT_ALL) || - (dwFlags & DIDFT_AXIS)) { - BYTE axes, i; - -#ifdef JSIOCGAXES - if (-1==ioctl(xfd,JSIOCGAXES,&axes)) - axes = 2; +#if !defined(__STRICT_ANSI__) && defined(__GNUC__) +# define XCAST(fun) (typeof(ddi7avt.fn##fun)) +#else +# define XCAST(fun) (void*) #endif - for (i = 0; i < axes; i++) { - switch (i) { - case 0: - ddoi.guidType = GUID_XAxis; - ddoi.dwOfs = DIJOFS_X; - break; - case 1: - ddoi.guidType = GUID_YAxis; - ddoi.dwOfs = DIJOFS_Y; - break; - case 2: - ddoi.guidType = GUID_ZAxis; - ddoi.dwOfs = DIJOFS_Z; - break; - default: - ddoi.guidType = GUID_Unknown; - ddoi.dwOfs = DIJOFS_Z + (i - 2) * sizeof(LONG); - } - ddoi.dwType = DIDFT_MAKEINSTANCE((0x0001 << i) << WINE_JOYSTICK_AXIS_BASE) | DIDFT_ABSAXIS; - sprintf(ddoi.tszName, "%d-Axis", i); - _dump_OBJECTINSTANCEA(&ddoi); - if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK; - } - } - - if ((dwFlags == DIDFT_ALL) || - (dwFlags & DIDFT_BUTTON)) { - BYTE buttons, i; - -#ifdef JSIOCGBUTTONS - if (-1==ioctl(xfd,JSIOCGAXES,&buttons)) - buttons = 2; -#endif - - /* The DInput SDK says that GUID_Button is only for mouse buttons but well... */ - ddoi.guidType = GUID_Button; - - for (i = 0; i < buttons; i++) { - ddoi.dwOfs = DIJOFS_BUTTON(i); - ddoi.dwType = DIDFT_MAKEINSTANCE((0x0001 << i) << WINE_JOYSTICK_BUTTON_BASE) | DIDFT_PSHBUTTON; - sprintf(ddoi.tszName, "%d-Button", i); - _dump_OBJECTINSTANCEA(&ddoi); - if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK; - } - } - - if (xfd!=This->joyfd) - close(xfd); - - return DI_OK; -} - -/****************************************************************************** - * GetProperty : get input device properties - */ -static HRESULT WINAPI JoystickAImpl_GetProperty(LPDIRECTINPUTDEVICE2A iface, - REFGUID rguid, - LPDIPROPHEADER pdiph) -{ - ICOM_THIS(JoystickAImpl,iface); - - TRACE("(this=%p,%s,%p): stub!\n", - iface, debugstr_guid(rguid), pdiph); - - if (TRACE_ON(dinput)) - _dump_DIPROPHEADER(pdiph); - - if (!HIWORD(rguid)) { - switch ((DWORD)rguid) { - case (DWORD) DIPROP_BUFFERSIZE: { - LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph; - - TRACE(" return buffersize = %d\n",This->queue_len); - pd->dwData = This->queue_len; - break; - } - - case (DWORD) DIPROP_RANGE: { - LPDIPROPRANGE pr = (LPDIPROPRANGE) pdiph; - - if ((pdiph->dwHow == DIPH_BYID) && - (pdiph->dwObj & DIDFT_ABSAXIS)) { - /* The app is querying the current range of the axis : return the lMin and lMax values */ - pr->lMin = This->lMin; - pr->lMax = This->lMax; - } - - break; - } - - default: - FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,debugstr_guid(rguid)); - break; - } - } - - - return DI_OK; -} - -#endif - -/****************************************************************************/ -/****************************************************************************/ - -static ICOM_VTABLE(IDirectInputDevice2A) SysKeyboardAvt = -{ +static ICOM_VTABLE(IDirectInput7A) ddi7avt = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE - IDirectInputDevice2AImpl_QueryInterface, - IDirectInputDevice2AImpl_AddRef, - IDirectInputDevice2AImpl_Release, - SysKeyboardAImpl_GetCapabilities, - IDirectInputDevice2AImpl_EnumObjects, - IDirectInputDevice2AImpl_GetProperty, - SysKeyboardAImpl_SetProperty, - SysKeyboardAImpl_Acquire, - SysKeyboardAImpl_Unacquire, - SysKeyboardAImpl_GetDeviceState, - SysKeyboardAImpl_GetDeviceData, - IDirectInputDevice2AImpl_SetDataFormat, - IDirectInputDevice2AImpl_SetEventNotification, - IDirectInputDevice2AImpl_SetCooperativeLevel, - IDirectInputDevice2AImpl_GetObjectInfo, - IDirectInputDevice2AImpl_GetDeviceInfo, - IDirectInputDevice2AImpl_RunControlPanel, - IDirectInputDevice2AImpl_Initialize, - IDirectInputDevice2AImpl_CreateEffect, - IDirectInputDevice2AImpl_EnumEffects, - IDirectInputDevice2AImpl_GetEffectInfo, - IDirectInputDevice2AImpl_GetForceFeedbackState, - IDirectInputDevice2AImpl_SendForceFeedbackCommand, - IDirectInputDevice2AImpl_EnumCreatedEffectObjects, - IDirectInputDevice2AImpl_Escape, - IDirectInputDevice2AImpl_Poll, - IDirectInputDevice2AImpl_SendDeviceData, + 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, + IDirectInput7AImpl_CreateDeviceEx }; - -static ICOM_VTABLE(IDirectInputDevice2A) SysMouseAvt = -{ - ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE - IDirectInputDevice2AImpl_QueryInterface, - IDirectInputDevice2AImpl_AddRef, - SysMouseAImpl_Release, - SysMouseAImpl_GetCapabilities, - SysMouseAImpl_EnumObjects, - SysMouseAImpl_GetProperty, - SysMouseAImpl_SetProperty, - SysMouseAImpl_Acquire, - SysMouseAImpl_Unacquire, - SysMouseAImpl_GetDeviceState, - SysMouseAImpl_GetDeviceData, - SysMouseAImpl_SetDataFormat, - SysMouseAImpl_SetEventNotification, - SysMouseAImpl_SetCooperativeLevel, - IDirectInputDevice2AImpl_GetObjectInfo, - IDirectInputDevice2AImpl_GetDeviceInfo, - IDirectInputDevice2AImpl_RunControlPanel, - IDirectInputDevice2AImpl_Initialize, - IDirectInputDevice2AImpl_CreateEffect, - IDirectInputDevice2AImpl_EnumEffects, - IDirectInputDevice2AImpl_GetEffectInfo, - IDirectInputDevice2AImpl_GetForceFeedbackState, - IDirectInputDevice2AImpl_SendForceFeedbackCommand, - IDirectInputDevice2AImpl_EnumCreatedEffectObjects, - IDirectInputDevice2AImpl_Escape, - IDirectInputDevice2AImpl_Poll, - IDirectInputDevice2AImpl_SendDeviceData, -}; - -#ifdef HAVE_LINUX_22_JOYSTICK_API -static ICOM_VTABLE(IDirectInputDevice2A) JoystickAvt = -{ - ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE - IDirectInputDevice2AImpl_QueryInterface, - IDirectInputDevice2AImpl_AddRef, - JoystickAImpl_Release, - JoystickAImpl_GetCapabilities, - JoystickAImpl_EnumObjects, - JoystickAImpl_GetProperty, - JoystickAImpl_SetProperty, - JoystickAImpl_Acquire, - JoystickAImpl_Unacquire, - JoystickAImpl_GetDeviceState, - JoystickAImpl_GetDeviceData, - JoystickAImpl_SetDataFormat, - JoystickAImpl_SetEventNotification, - IDirectInputDevice2AImpl_SetCooperativeLevel, - IDirectInputDevice2AImpl_GetObjectInfo, - IDirectInputDevice2AImpl_GetDeviceInfo, - IDirectInputDevice2AImpl_RunControlPanel, - IDirectInputDevice2AImpl_Initialize, - IDirectInputDevice2AImpl_CreateEffect, - IDirectInputDevice2AImpl_EnumEffects, - IDirectInputDevice2AImpl_GetEffectInfo, - IDirectInputDevice2AImpl_GetForceFeedbackState, - IDirectInputDevice2AImpl_SendForceFeedbackCommand, - IDirectInputDevice2AImpl_EnumCreatedEffectObjects, - IDirectInputDevice2AImpl_Escape, - JoystickAImpl_Poll, - IDirectInputDevice2AImpl_SendDeviceData, -}; -#endif +#undef XCAST /*********************************************************************** * DllCanUnloadNow (DINPUT.@) diff --git a/dlls/dinput/dinput_private.h b/dlls/dinput/dinput_private.h new file mode 100644 index 00000000000..869f4a7da08 --- /dev/null +++ b/dlls/dinput/dinput_private.h @@ -0,0 +1,26 @@ +#ifndef __WINE_DLLS_DINPUT_DINPUT_PRIVATE_H +#define __WINE_DLLS_DINPUT_DINPUT_PRIVATE_H + +#include "winbase.h" +#include "dinput.h" + +/* Implementation specification */ +typedef struct IDirectInputAImpl IDirectInputAImpl; +struct IDirectInputAImpl +{ + ICOM_VFIELD(IDirectInputA); + DWORD ref; + + /* Used to have an unique sequence number for all the events */ + DWORD evsequence; +}; + +/* Function called by all devices that Wine supports */ +typedef struct dinput_device { + BOOL (*enum_device)(DWORD dwDevType, DWORD dwFlags, LPCDIDEVICEINSTANCEA lpddi); + HRESULT (*create_device)(IDirectInputAImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev); +} dinput_device; + +extern void dinput_register_device(dinput_device *device) ; + +#endif /* __WINE_DLLS_DINPUT_DINPUT_PRIVATE_H */ diff --git a/dlls/dinput/joystick/linux.c b/dlls/dinput/joystick/linux.c new file mode 100644 index 00000000000..0d1b445f1a5 --- /dev/null +++ b/dlls/dinput/joystick/linux.c @@ -0,0 +1,611 @@ +/* DirectInput Joystick device + * + * Copyright 1998 Marcus Meissner + * Copyright 1998,1999 Lionel Ulmer + * + */ + +#include "config.h" + +#ifdef HAVE_LINUX_22_JOYSTICK_API + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_ERRNO_H +# include +#endif +#include +#define JOYDEV "/dev/js0" + +#include "debugtools.h" +#include "winbase.h" +#include "winerror.h" +#include "windef.h" +#include "dinput.h" + +#include "dinput_private.h" +#include "device_private.h" + +DEFAULT_DEBUG_CHANNEL(dinput); + +/* Wine joystick driver object instances */ +#define WINE_JOYSTICK_AXIS_BASE 0 +#define WINE_JOYSTICK_BUTTON_BASE 8 + +typedef struct JoystickAImpl JoystickAImpl; +static ICOM_VTABLE(IDirectInputDevice2A) JoystickAvt; +static ICOM_VTABLE(IDirectInputDevice7A) Joystick7Avt; +struct JoystickAImpl +{ + /* IDirectInputDevice2AImpl */ + ICOM_VFIELD(IDirectInputDevice2A); + DWORD ref; + GUID guid; + + /* The 'parent' DInput */ + IDirectInputAImpl *dinput; + + /* joystick private */ + int joyfd; + LPDIDATAFORMAT df; + HANDLE hEvent; + LONG lMin,lMax,deadzone; + LPDIDEVICEOBJECTDATA data_queue; + int queue_pos, queue_len; + DIJOYSTATE js; +}; + +static GUID DInput_Wine_Joystick_GUID = { /* 9e573ed9-7734-11d2-8d4a-23903fb6bdf7 */ + 0x9e573ed9, + 0x7734, + 0x11d2, + {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7} +}; + +static BOOL joydev_enum_device(DWORD dwDevType, DWORD dwFlags, LPCDIDEVICEINSTANCEA lpddi) +{ + if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_JOYSTICK)) { + /* check whether we have a joystick */ + if ((access(JOYDEV,O_RDONLY) != -1) || (errno!=ENODEV && errno!=ENOENT)) { + TRACE("Enumerating the Joystick device\n"); + + /* Return joystick */ + lpddi->guidInstance = GUID_Joystick; + lpddi->guidProduct = DInput_Wine_Joystick_GUID; + /* we only support traditional joysticks for now */ + lpddi->dwDevType = DIDEVTYPE_JOYSTICK | DIDEVTYPEJOYSTICK_TRADITIONAL; + strcpy(lpddi->tszInstanceName, "Joystick"); + /* ioctl JSIOCGNAME(len) */ + strcpy(lpddi->tszProductName, "Wine Joystick"); + + return TRUE; + } + } + + return FALSE; +} + +static JoystickAImpl *alloc_device(REFGUID rguid, ICOM_VTABLE(IDirectInputDevice2A) *jvt, IDirectInputAImpl *dinput) +{ + JoystickAImpl* newDevice; + + newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(JoystickAImpl)); + newDevice->ref = 1; + ICOM_VTBL(newDevice) = jvt; + newDevice->joyfd = -1; + newDevice->lMin = -32768; + newDevice->lMax = +32767; + newDevice->dinput = dinput; + memcpy(&(newDevice->guid),rguid,sizeof(*rguid)); + + return newDevice; +} + +static HRESULT joydev_create_device(IDirectInputAImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev) +{ + if ((IsEqualGUID(&GUID_Joystick,rguid)) || + (IsEqualGUID(&DInput_Wine_Joystick_GUID,rguid))) { + if ((riid == NULL) || (IsEqualGUID(&IID_IDirectInputDevice2A,riid)) || (IsEqualGUID(&IID_IDirectInputDevice2A,riid))) { + *pdev=(IDirectInputDeviceA*) alloc_device(rguid, &JoystickAvt, dinput); + + TRACE("Creating a Joystick device (%p)\n", *pdev); + return DI_OK; + } else if (IsEqualGUID(&IID_IDirectInputDevice7A,riid)) { + *pdev=(IDirectInputDeviceA*) alloc_device(rguid, (ICOM_VTABLE(IDirectInputDevice2A) *) &Joystick7Avt, dinput); + + TRACE("Creating a Joystick DInput7A device (%p)\n", *pdev); + return DI_OK; + } else + return DIERR_NOINTERFACE; + } + + return DIERR_DEVICENOTREG; +} + +static dinput_device joydev = { + joydev_enum_device, + joydev_create_device +}; + +DECL_GLOBAL_CONSTRUCTOR(joydev_register) { dinput_register_device(&joydev); } + +/****************************************************************************** + * Joystick + */ +static ULONG WINAPI JoystickAImpl_Release(LPDIRECTINPUTDEVICE2A iface) +{ + ICOM_THIS(JoystickAImpl,iface); + + This->ref--; + if (This->ref) + return This->ref; + + /* Free the data queue */ + if (This->data_queue != NULL) + HeapFree(GetProcessHeap(),0,This->data_queue); + + /* Free the DataFormat */ + HeapFree(GetProcessHeap(), 0, This->df); + + HeapFree(GetProcessHeap(),0,This); + return 0; +} + +/****************************************************************************** + * SetDataFormat : the application can choose the format of the data + * the device driver sends back with GetDeviceState. + */ +static HRESULT WINAPI JoystickAImpl_SetDataFormat( + LPDIRECTINPUTDEVICE2A iface,LPCDIDATAFORMAT df +) +{ + ICOM_THIS(JoystickAImpl,iface); + int i; + + TRACE("(this=%p,%p)\n",This,df); + + TRACE("(df.dwSize=%ld)\n",df->dwSize); + TRACE("(df.dwObjsize=%ld)\n",df->dwObjSize); + TRACE("(df.dwFlags=0x%08lx)\n",df->dwFlags); + TRACE("(df.dwDataSize=%ld)\n",df->dwDataSize); + TRACE("(df.dwNumObjs=%ld)\n",df->dwNumObjs); + + for (i=0;idwNumObjs;i++) { + TRACE("df.rgodf[%d].guid %s (%p)\n",i,debugstr_guid(df->rgodf[i].pguid), df->rgodf[i].pguid); + TRACE("df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs); + TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType)); + TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags); + } + + /* Store the new data format */ + This->df = HeapAlloc(GetProcessHeap(),0,df->dwSize); + memcpy(This->df, df, df->dwSize); + This->df->rgodf = HeapAlloc(GetProcessHeap(),0,df->dwNumObjs*df->dwObjSize); + memcpy(This->df->rgodf,df->rgodf,df->dwNumObjs*df->dwObjSize); + + return 0; +} + +/****************************************************************************** + * Acquire : gets exclusive control of the joystick + */ +static HRESULT WINAPI JoystickAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface) +{ + ICOM_THIS(JoystickAImpl,iface); + + TRACE("(this=%p)\n",This); + if (This->joyfd!=-1) + return 0; + This->joyfd=open(JOYDEV,O_RDONLY); + if (This->joyfd==-1) + return DIERR_NOTFOUND; + return 0; +} + +/****************************************************************************** + * Unacquire : frees the joystick + */ +static HRESULT WINAPI JoystickAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface) +{ + ICOM_THIS(JoystickAImpl,iface); + + TRACE("(this=%p)\n",This); + if (This->joyfd!=-1) { + close(This->joyfd); + This->joyfd = -1; + } + return DI_OK; +} + +#define map_axis(val) ((val+32768)*(This->lMax-This->lMin)/65536+This->lMin) + +static void joy_polldev(JoystickAImpl *This) { + struct timeval tv; + fd_set readfds; + struct js_event jse; + + if (This->joyfd==-1) + return; + while (1) { + memset(&tv,0,sizeof(tv)); + FD_ZERO(&readfds);FD_SET(This->joyfd,&readfds); + if (1>select(This->joyfd+1,&readfds,NULL,NULL,&tv)) + return; + /* we have one event, so we can read */ + if (sizeof(jse)!=read(This->joyfd,&jse,sizeof(jse))) { + return; + } + TRACE("js_event: type 0x%x, number %d, value %d\n",jse.type,jse.number,jse.value); + if (jse.type & JS_EVENT_BUTTON) { + GEN_EVENT(DIJOFS_BUTTON(jse.number),jse.value?0x80:0x00,jse.time,(This->dinput->evsequence)++); + This->js.rgbButtons[jse.number] = jse.value?0x80:0x00; + } + if (jse.type & JS_EVENT_AXIS) { + switch (jse.number) { + case 0: + GEN_EVENT(jse.number*4,jse.value,jse.time,(This->dinput->evsequence)++); + This->js.lX = map_axis(jse.value); + break; + case 1: + GEN_EVENT(jse.number*4,jse.value,jse.time,(This->dinput->evsequence)++); + This->js.lY = map_axis(jse.value); + break; + case 2: + GEN_EVENT(jse.number*4,jse.value,jse.time,(This->dinput->evsequence)++); + This->js.lZ = map_axis(jse.value); + break; + default: + FIXME("more then 3 axes (%d) not handled!\n",jse.number); + break; + } + } + } +} + +/****************************************************************************** + * GetDeviceState : returns the "state" of the joystick. + * + */ +static HRESULT WINAPI JoystickAImpl_GetDeviceState( + LPDIRECTINPUTDEVICE2A iface,DWORD len,LPVOID ptr +) { + ICOM_THIS(JoystickAImpl,iface); + + joy_polldev(This); + TRACE("(this=%p,0x%08lx,%p)\n",This,len,ptr); + if (len != sizeof(DIJOYSTATE)) { + FIXME("len %ld is not sizeof(DIJOYSTATE), unsupported format.\n",len); + } + memcpy(ptr,&(This->js),len); + This->queue_pos = 0; + return 0; +} + +/****************************************************************************** + * GetDeviceData : gets buffered input data. + */ +static HRESULT WINAPI JoystickAImpl_GetDeviceData(LPDIRECTINPUTDEVICE2A iface, + DWORD dodsize, + LPDIDEVICEOBJECTDATA dod, + LPDWORD entries, + DWORD flags +) { + ICOM_THIS(JoystickAImpl,iface); + + FIXME("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx),STUB!\n",This,dodsize,*entries,flags); + + joy_polldev(This); + if (flags & DIGDD_PEEK) + FIXME("DIGDD_PEEK\n"); + + if (dod == NULL) { + } else { + } + return 0; +} + +/****************************************************************************** + * SetProperty : change input device properties + */ +static HRESULT WINAPI JoystickAImpl_SetProperty(LPDIRECTINPUTDEVICE2A iface, + REFGUID rguid, + LPCDIPROPHEADER ph) +{ + ICOM_THIS(JoystickAImpl,iface); + + FIXME("(this=%p,%s,%p)\n",This,debugstr_guid(rguid),ph); + FIXME("ph.dwSize = %ld, ph.dwHeaderSize =%ld, ph.dwObj = %ld, ph.dwHow= %ld\n",ph->dwSize, ph->dwHeaderSize,ph->dwObj,ph->dwHow); + + if (!HIWORD(rguid)) { + switch ((DWORD)rguid) { + case (DWORD) DIPROP_BUFFERSIZE: { + LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph; + + FIXME("buffersize = %ld\n",pd->dwData); + break; + } + case (DWORD)DIPROP_RANGE: { + LPCDIPROPRANGE pr = (LPCDIPROPRANGE)ph; + + FIXME("proprange(%ld,%ld)\n",pr->lMin,pr->lMax); + This->lMin = pr->lMin; + This->lMax = pr->lMax; + break; + } + case (DWORD)DIPROP_DEADZONE: { + LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph; + + FIXME("deadzone(%ld)\n",pd->dwData); + This->deadzone = pd->dwData; + break; + } + default: + FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,debugstr_guid(rguid)); + break; + } + } + return 0; +} + +/****************************************************************************** + * SetEventNotification : specifies event to be sent on state change + */ +static HRESULT WINAPI JoystickAImpl_SetEventNotification( + LPDIRECTINPUTDEVICE2A iface, HANDLE hnd +) { + ICOM_THIS(JoystickAImpl,iface); + + TRACE("(this=%p,0x%08lx)\n",This,(DWORD)hnd); + This->hEvent = hnd; + return DI_OK; +} + +static HRESULT WINAPI JoystickAImpl_GetCapabilities( + LPDIRECTINPUTDEVICE2A iface, + LPDIDEVCAPS lpDIDevCaps) +{ + ICOM_THIS(JoystickAImpl,iface); + BYTE axes,buttons; + int xfd = This->joyfd; + + TRACE("%p->(%p)\n",iface,lpDIDevCaps); + if (xfd==-1) + xfd = open(JOYDEV,O_RDONLY); + lpDIDevCaps->dwFlags = DIDC_ATTACHED; + lpDIDevCaps->dwDevType = DIDEVTYPE_JOYSTICK; +#ifdef JSIOCGAXES + if (-1==ioctl(xfd,JSIOCGAXES,&axes)) + axes = 2; + lpDIDevCaps->dwAxes = axes; +#endif +#ifdef JSIOCGBUTTONS + if (-1==ioctl(xfd,JSIOCGAXES,&buttons)) + buttons = 2; + lpDIDevCaps->dwButtons = buttons; +#endif + if (xfd!=This->joyfd) + close(xfd); + return DI_OK; +} +static HRESULT WINAPI JoystickAImpl_Poll(LPDIRECTINPUTDEVICE2A iface) { + ICOM_THIS(JoystickAImpl,iface); + TRACE("(),stub!\n"); + + joy_polldev(This); + return DI_OK; +} + +/****************************************************************************** + * EnumObjects : enumerate the different buttons and axis... + */ +static HRESULT WINAPI JoystickAImpl_EnumObjects( + LPDIRECTINPUTDEVICE2A iface, + LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback, + LPVOID lpvRef, + DWORD dwFlags) +{ + ICOM_THIS(JoystickAImpl,iface); + DIDEVICEOBJECTINSTANCEA ddoi; + int xfd = This->joyfd; + + TRACE("(this=%p,%p,%p,%08lx)\n", This, lpCallback, lpvRef, dwFlags); + if (TRACE_ON(dinput)) { + DPRINTF(" - flags = "); + _dump_EnumObjects_flags(dwFlags); + DPRINTF("\n"); + } + + /* Only the fields till dwFFMaxForce are relevant */ + ddoi.dwSize = FIELD_OFFSET(DIDEVICEOBJECTINSTANCEA, dwFFMaxForce); + + /* For the joystick, do as is done in the GetCapabilities function */ + if ((dwFlags == DIDFT_ALL) || + (dwFlags & DIDFT_AXIS)) { + BYTE axes, i; + +#ifdef JSIOCGAXES + if (-1==ioctl(xfd,JSIOCGAXES,&axes)) + axes = 2; +#endif + + for (i = 0; i < axes; i++) { + switch (i) { + case 0: + ddoi.guidType = GUID_XAxis; + ddoi.dwOfs = DIJOFS_X; + break; + case 1: + ddoi.guidType = GUID_YAxis; + ddoi.dwOfs = DIJOFS_Y; + break; + case 2: + ddoi.guidType = GUID_ZAxis; + ddoi.dwOfs = DIJOFS_Z; + break; + default: + ddoi.guidType = GUID_Unknown; + ddoi.dwOfs = DIJOFS_Z + (i - 2) * sizeof(LONG); + } + ddoi.dwType = DIDFT_MAKEINSTANCE((0x0001 << i) << WINE_JOYSTICK_AXIS_BASE) | DIDFT_ABSAXIS; + sprintf(ddoi.tszName, "%d-Axis", i); + _dump_OBJECTINSTANCEA(&ddoi); + if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK; + } + } + + if ((dwFlags == DIDFT_ALL) || + (dwFlags & DIDFT_BUTTON)) { + BYTE buttons, i; + +#ifdef JSIOCGBUTTONS + if (-1==ioctl(xfd,JSIOCGAXES,&buttons)) + buttons = 2; +#endif + + /* The DInput SDK says that GUID_Button is only for mouse buttons but well... */ + ddoi.guidType = GUID_Button; + + for (i = 0; i < buttons; i++) { + ddoi.dwOfs = DIJOFS_BUTTON(i); + ddoi.dwType = DIDFT_MAKEINSTANCE((0x0001 << i) << WINE_JOYSTICK_BUTTON_BASE) | DIDFT_PSHBUTTON; + sprintf(ddoi.tszName, "%d-Button", i); + _dump_OBJECTINSTANCEA(&ddoi); + if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK; + } + } + + if (xfd!=This->joyfd) + close(xfd); + + return DI_OK; +} + +/****************************************************************************** + * GetProperty : get input device properties + */ +static HRESULT WINAPI JoystickAImpl_GetProperty(LPDIRECTINPUTDEVICE2A iface, + REFGUID rguid, + LPDIPROPHEADER pdiph) +{ + ICOM_THIS(JoystickAImpl,iface); + + TRACE("(this=%p,%s,%p): stub!\n", + iface, debugstr_guid(rguid), pdiph); + + if (TRACE_ON(dinput)) + _dump_DIPROPHEADER(pdiph); + + if (!HIWORD(rguid)) { + switch ((DWORD)rguid) { + case (DWORD) DIPROP_BUFFERSIZE: { + LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph; + + TRACE(" return buffersize = %d\n",This->queue_len); + pd->dwData = This->queue_len; + break; + } + + case (DWORD) DIPROP_RANGE: { + LPDIPROPRANGE pr = (LPDIPROPRANGE) pdiph; + + if ((pdiph->dwHow == DIPH_BYID) && + (pdiph->dwObj & DIDFT_ABSAXIS)) { + /* The app is querying the current range of the axis : return the lMin and lMax values */ + pr->lMin = This->lMin; + pr->lMax = This->lMax; + } + + break; + } + + default: + FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,debugstr_guid(rguid)); + break; + } + } + + + return DI_OK; +} + +static ICOM_VTABLE(IDirectInputDevice2A) JoystickAvt = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + IDirectInputDevice2AImpl_QueryInterface, + IDirectInputDevice2AImpl_AddRef, + JoystickAImpl_Release, + JoystickAImpl_GetCapabilities, + JoystickAImpl_EnumObjects, + JoystickAImpl_GetProperty, + JoystickAImpl_SetProperty, + JoystickAImpl_Acquire, + JoystickAImpl_Unacquire, + JoystickAImpl_GetDeviceState, + JoystickAImpl_GetDeviceData, + JoystickAImpl_SetDataFormat, + JoystickAImpl_SetEventNotification, + IDirectInputDevice2AImpl_SetCooperativeLevel, + IDirectInputDevice2AImpl_GetObjectInfo, + IDirectInputDevice2AImpl_GetDeviceInfo, + IDirectInputDevice2AImpl_RunControlPanel, + IDirectInputDevice2AImpl_Initialize, + IDirectInputDevice2AImpl_CreateEffect, + IDirectInputDevice2AImpl_EnumEffects, + IDirectInputDevice2AImpl_GetEffectInfo, + IDirectInputDevice2AImpl_GetForceFeedbackState, + IDirectInputDevice2AImpl_SendForceFeedbackCommand, + IDirectInputDevice2AImpl_EnumCreatedEffectObjects, + IDirectInputDevice2AImpl_Escape, + JoystickAImpl_Poll, + IDirectInputDevice2AImpl_SendDeviceData, +}; + +#if !defined(__STRICT_ANSI__) && defined(__GNUC__) +# define XCAST(fun) (typeof(Joystick7Avt.fn##fun)) +#else +# define XCAST(fun) (void*) +#endif + +static ICOM_VTABLE(IDirectInputDevice7A) Joystick7Avt = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + XCAST(QueryInterface)IDirectInputDevice2AImpl_QueryInterface, + XCAST(AddRef)IDirectInputDevice2AImpl_AddRef, + XCAST(Release)JoystickAImpl_Release, + XCAST(GetCapabilities)JoystickAImpl_GetCapabilities, + XCAST(EnumObjects)JoystickAImpl_EnumObjects, + XCAST(GetProperty)JoystickAImpl_GetProperty, + XCAST(SetProperty)JoystickAImpl_SetProperty, + XCAST(Acquire)JoystickAImpl_Acquire, + XCAST(Unacquire)JoystickAImpl_Unacquire, + XCAST(GetDeviceState)JoystickAImpl_GetDeviceState, + XCAST(GetDeviceData)JoystickAImpl_GetDeviceData, + XCAST(SetDataFormat)JoystickAImpl_SetDataFormat, + XCAST(SetEventNotification)JoystickAImpl_SetEventNotification, + XCAST(SetCooperativeLevel)IDirectInputDevice2AImpl_SetCooperativeLevel, + XCAST(GetObjectInfo)IDirectInputDevice2AImpl_GetObjectInfo, + XCAST(GetDeviceInfo)IDirectInputDevice2AImpl_GetDeviceInfo, + XCAST(RunControlPanel)IDirectInputDevice2AImpl_RunControlPanel, + XCAST(Initialize)IDirectInputDevice2AImpl_Initialize, + XCAST(CreateEffect)IDirectInputDevice2AImpl_CreateEffect, + XCAST(EnumEffects)IDirectInputDevice2AImpl_EnumEffects, + XCAST(GetEffectInfo)IDirectInputDevice2AImpl_GetEffectInfo, + XCAST(GetForceFeedbackState)IDirectInputDevice2AImpl_GetForceFeedbackState, + XCAST(SendForceFeedbackCommand)IDirectInputDevice2AImpl_SendForceFeedbackCommand, + XCAST(EnumCreatedEffectObjects)IDirectInputDevice2AImpl_EnumCreatedEffectObjects, + XCAST(Escape)IDirectInputDevice2AImpl_Escape, + XCAST(Poll)JoystickAImpl_Poll, + XCAST(SendDeviceData)IDirectInputDevice2AImpl_SendDeviceData, + IDirectInputDevice7AImpl_EnumEffectsInFile, + IDirectInputDevice7AImpl_WriteEffectToFile +}; + +#undef XCAST + +#endif /* HAVE_LINUX_22_JOYSTICK_API */ diff --git a/dlls/dinput/keyboard/main.c b/dlls/dinput/keyboard/main.c new file mode 100644 index 00000000000..ac372583528 --- /dev/null +++ b/dlls/dinput/keyboard/main.c @@ -0,0 +1,307 @@ +/* DirectInput Keyboard device + * + * Copyright 1998 Marcus Meissner + * Copyright 1998,1999 Lionel Ulmer + * + */ + +#include "config.h" +#include +#ifdef HAVE_SYS_ERRNO_H +# include +#endif + +#include "debugtools.h" +#include "user.h" +#include "winerror.h" +#include "windef.h" +#include "dinput.h" + +#include "dinput_private.h" +#include "device_private.h" + +DEFAULT_DEBUG_CHANNEL(dinput); + +extern BYTE InputKeyStateTable[256]; +extern int min_keycode, max_keycode; +extern WORD keyc2vkey[256]; + +static ICOM_VTABLE(IDirectInputDevice2A) SysKeyboardAvt; +static ICOM_VTABLE(IDirectInputDevice7A) SysKeyboard7Avt; + +typedef struct SysKeyboardAImpl SysKeyboardAImpl; +struct SysKeyboardAImpl +{ + /* IDirectInputDevice2AImpl */ + ICOM_VFIELD(IDirectInputDevice2A); + DWORD ref; + GUID guid; + + IDirectInputAImpl *dinput; + + /* SysKeyboardAImpl */ + BYTE keystate[256]; + KEYBOARD_CONFIG initial_config; + int acquired; +}; + +static GUID DInput_Wine_Keyboard_GUID = { /* 0ab8648a-7735-11d2-8c73-71df54a96441 */ + 0x0ab8648a, + 0x7735, + 0x11d2, + {0x8c, 0x73, 0x71, 0xdf, 0x54, 0xa9, 0x64, 0x41} +}; + +static BOOL keyboarddev_enum_device(DWORD dwDevType, DWORD dwFlags, LPCDIDEVICEINSTANCEA lpddi) +{ + if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_KEYBOARD)) { + TRACE("Enumerating the Keyboard device\n"); + + lpddi->guidInstance = GUID_SysKeyboard;/* DInput's GUID */ + lpddi->guidProduct = DInput_Wine_Keyboard_GUID; /* Vendor's GUID */ + lpddi->dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_UNKNOWN << 8); + strcpy(lpddi->tszInstanceName, "Keyboard"); + strcpy(lpddi->tszProductName, "Wine Keyboard"); + + return TRUE; + } + + return FALSE; +} + +static SysKeyboardAImpl *alloc_device(REFGUID rguid, ICOM_VTABLE(IDirectInputDevice2A) *kvt, IDirectInputAImpl *dinput) +{ + SysKeyboardAImpl* newDevice; + newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysKeyboardAImpl)); + newDevice->ref = 1; + ICOM_VTBL(newDevice) = kvt; + memcpy(&(newDevice->guid),rguid,sizeof(*rguid)); + memset(newDevice->keystate,0,256); + newDevice->dinput = dinput; + + return newDevice; +} + + +static HRESULT keyboarddev_create_device(IDirectInputAImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev) +{ + if ((IsEqualGUID(&GUID_SysKeyboard,rguid)) || /* Generic Keyboard */ + (IsEqualGUID(&DInput_Wine_Keyboard_GUID,rguid))) { /* Wine Keyboard */ + if ((riid == NULL) || (IsEqualGUID(&IID_IDirectInputDevice2A,riid)) || (IsEqualGUID(&IID_IDirectInputDevice2A,riid))) { + *pdev=(IDirectInputDeviceA*) alloc_device(rguid, &SysKeyboardAvt, dinput); + + TRACE("Creating a Keyboard device (%p)\n", *pdev); + return DI_OK; + } else if (IsEqualGUID(&IID_IDirectInputDevice7A,riid)) { + *pdev=(IDirectInputDeviceA*) alloc_device(rguid, (ICOM_VTABLE(IDirectInputDevice2A) *) &SysKeyboard7Avt, dinput); + + TRACE("Creating a Keyboard DInput7A device (%p)\n", *pdev); + return DI_OK; + } else + return DIERR_NOINTERFACE; + } + + return DIERR_DEVICENOTREG; +} + +static dinput_device keyboarddev = { + keyboarddev_enum_device, + keyboarddev_create_device +}; + +DECL_GLOBAL_CONSTRUCTOR(keyboarddev_register) { dinput_register_device(&keyboarddev); } + +static HRESULT WINAPI SysKeyboardAImpl_SetProperty( + LPDIRECTINPUTDEVICE2A iface,REFGUID rguid,LPCDIPROPHEADER ph +) +{ + ICOM_THIS(SysKeyboardAImpl,iface); + + TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(rguid),ph); + TRACE("(size=%ld,headersize=%ld,obj=%ld,how=%ld\n", + ph->dwSize,ph->dwHeaderSize,ph->dwObj,ph->dwHow); + if (!HIWORD(rguid)) { + switch ((DWORD)rguid) { + case (DWORD) DIPROP_BUFFERSIZE: { + LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph; + + TRACE("(buffersize=%ld)\n",pd->dwData); + break; + } + default: + WARN("Unknown type %ld\n",(DWORD)rguid); + break; + } + } + return 0; +} + +static HRESULT WINAPI SysKeyboardAImpl_GetDeviceState( + LPDIRECTINPUTDEVICE2A iface,DWORD len,LPVOID ptr +) +{ + return USER_Driver.pGetDIState(len, ptr)?DI_OK:E_FAIL; +} + +static HRESULT WINAPI SysKeyboardAImpl_GetDeviceData( + LPDIRECTINPUTDEVICE2A iface,DWORD dodsize,LPDIDEVICEOBJECTDATA dod, + LPDWORD entries,DWORD flags +) +{ + ICOM_THIS(SysKeyboardAImpl,iface); + HRESULT ret; + int i; + + TRACE("(this=%p,%ld,%p,%p(%ld)),0x%08lx)\n", + This,dodsize,dod,entries,entries?*entries:0,flags); + + ret=USER_Driver.pGetDIData( + This->keystate, dodsize, dod, entries, flags)?DI_OK:E_FAIL; + for (i=0;i<*entries;i++) { + dod[i].dwTimeStamp = GetTickCount(); + dod[i].dwSequence = (This->dinput->evsequence)++; + } + return ret; +} + +static HRESULT WINAPI SysKeyboardAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface) +{ + ICOM_THIS(SysKeyboardAImpl,iface); + + TRACE("(this=%p)\n",This); + + if (This->acquired == 0) { + KEYBOARD_CONFIG no_auto; + + /* Save the original config */ + USER_Driver.pGetKeyboardConfig(&(This->initial_config)); + + /* Now, remove auto-repeat */ + no_auto.auto_repeat = FALSE; + USER_Driver.pSetKeyboardConfig(&no_auto, WINE_KEYBOARD_CONFIG_AUTO_REPEAT); + + This->acquired = 1; + } + + return DI_OK; +} + +static HRESULT WINAPI SysKeyboardAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface) +{ + ICOM_THIS(SysKeyboardAImpl,iface); + TRACE("(this=%p)\n",This); + + if (This->acquired == 1) { + /* Restore the original configuration */ + USER_Driver.pSetKeyboardConfig(&(This->initial_config), 0xFFFFFFFF); + This->acquired = 0; + } else { + ERR("Unacquiring a not-acquired device !!!\n"); + } + + return DI_OK; +} + +/****************************************************************************** + * GetCapabilities : get the device capablitites + */ +static HRESULT WINAPI SysKeyboardAImpl_GetCapabilities( + LPDIRECTINPUTDEVICE2A iface, + LPDIDEVCAPS lpDIDevCaps) +{ + ICOM_THIS(SysKeyboardAImpl,iface); + + TRACE("(this=%p,%p)\n",This,lpDIDevCaps); + + if (lpDIDevCaps->dwSize == sizeof(DIDEVCAPS)) { + lpDIDevCaps->dwFlags = DIDC_ATTACHED; + lpDIDevCaps->dwDevType = DIDEVTYPE_KEYBOARD; + lpDIDevCaps->dwAxes = 0; + lpDIDevCaps->dwButtons = 0; + lpDIDevCaps->dwPOVs = 0; + lpDIDevCaps->dwFFSamplePeriod = 0; + lpDIDevCaps->dwFFMinTimeResolution = 0; + lpDIDevCaps->dwFirmwareRevision = 100; + lpDIDevCaps->dwHardwareRevision = 100; + lpDIDevCaps->dwFFDriverVersion = 0; + } else { + /* DirectX 3.0 */ + FIXME("DirectX 3.0 not supported....\n"); + } + + return DI_OK; +} + +static ICOM_VTABLE(IDirectInputDevice2A) SysKeyboardAvt = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + IDirectInputDevice2AImpl_QueryInterface, + IDirectInputDevice2AImpl_AddRef, + IDirectInputDevice2AImpl_Release, + SysKeyboardAImpl_GetCapabilities, + IDirectInputDevice2AImpl_EnumObjects, + IDirectInputDevice2AImpl_GetProperty, + SysKeyboardAImpl_SetProperty, + SysKeyboardAImpl_Acquire, + SysKeyboardAImpl_Unacquire, + SysKeyboardAImpl_GetDeviceState, + SysKeyboardAImpl_GetDeviceData, + IDirectInputDevice2AImpl_SetDataFormat, + IDirectInputDevice2AImpl_SetEventNotification, + IDirectInputDevice2AImpl_SetCooperativeLevel, + IDirectInputDevice2AImpl_GetObjectInfo, + IDirectInputDevice2AImpl_GetDeviceInfo, + IDirectInputDevice2AImpl_RunControlPanel, + IDirectInputDevice2AImpl_Initialize, + IDirectInputDevice2AImpl_CreateEffect, + IDirectInputDevice2AImpl_EnumEffects, + IDirectInputDevice2AImpl_GetEffectInfo, + IDirectInputDevice2AImpl_GetForceFeedbackState, + IDirectInputDevice2AImpl_SendForceFeedbackCommand, + IDirectInputDevice2AImpl_EnumCreatedEffectObjects, + IDirectInputDevice2AImpl_Escape, + IDirectInputDevice2AImpl_Poll, + IDirectInputDevice2AImpl_SendDeviceData +}; + +#if !defined(__STRICT_ANSI__) && defined(__GNUC__) +# define XCAST(fun) (typeof(SysKeyboard7Avt.fn##fun)) +#else +# define XCAST(fun) (void*) +#endif + +static ICOM_VTABLE(IDirectInputDevice7A) SysKeyboard7Avt = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + XCAST(QueryInterface)IDirectInputDevice2AImpl_QueryInterface, + XCAST(AddRef)IDirectInputDevice2AImpl_AddRef, + XCAST(Release)IDirectInputDevice2AImpl_Release, + XCAST(GetCapabilities)SysKeyboardAImpl_GetCapabilities, + XCAST(EnumObjects)IDirectInputDevice2AImpl_EnumObjects, + XCAST(GetProperty)IDirectInputDevice2AImpl_GetProperty, + XCAST(SetProperty)SysKeyboardAImpl_SetProperty, + XCAST(Acquire)SysKeyboardAImpl_Acquire, + XCAST(Unacquire)SysKeyboardAImpl_Unacquire, + XCAST(GetDeviceState)SysKeyboardAImpl_GetDeviceState, + XCAST(GetDeviceData)SysKeyboardAImpl_GetDeviceData, + XCAST(SetDataFormat)IDirectInputDevice2AImpl_SetDataFormat, + XCAST(SetEventNotification)IDirectInputDevice2AImpl_SetEventNotification, + XCAST(SetCooperativeLevel)IDirectInputDevice2AImpl_SetCooperativeLevel, + XCAST(GetObjectInfo)IDirectInputDevice2AImpl_GetObjectInfo, + XCAST(GetDeviceInfo)IDirectInputDevice2AImpl_GetDeviceInfo, + XCAST(RunControlPanel)IDirectInputDevice2AImpl_RunControlPanel, + XCAST(Initialize)IDirectInputDevice2AImpl_Initialize, + XCAST(CreateEffect)IDirectInputDevice2AImpl_CreateEffect, + XCAST(EnumEffects)IDirectInputDevice2AImpl_EnumEffects, + XCAST(GetEffectInfo)IDirectInputDevice2AImpl_GetEffectInfo, + XCAST(GetForceFeedbackState)IDirectInputDevice2AImpl_GetForceFeedbackState, + XCAST(SendForceFeedbackCommand)IDirectInputDevice2AImpl_SendForceFeedbackCommand, + XCAST(EnumCreatedEffectObjects)IDirectInputDevice2AImpl_EnumCreatedEffectObjects, + XCAST(Escape)IDirectInputDevice2AImpl_Escape, + XCAST(Poll)IDirectInputDevice2AImpl_Poll, + XCAST(SendDeviceData)IDirectInputDevice2AImpl_SendDeviceData, + IDirectInputDevice7AImpl_EnumEffectsInFile, + IDirectInputDevice7AImpl_WriteEffectToFile +}; + +#undef XCAST diff --git a/dlls/dinput/mouse/main.c b/dlls/dinput/mouse/main.c new file mode 100644 index 00000000000..62e673b5347 --- /dev/null +++ b/dlls/dinput/mouse/main.c @@ -0,0 +1,967 @@ +/* DirectInput Mouse device + * + * Copyright 1998 Marcus Meissner + * Copyright 1998,1999 Lionel Ulmer + * + */ + +#include "config.h" +#include +#ifdef HAVE_SYS_ERRNO_H +# include +#endif + +#include "debugtools.h" +#include "input.h" +#include "user.h" +#include "winbase.h" +#include "wingdi.h" +#include "winerror.h" +#include "windef.h" +#include "mouse.h" +#include "winuser.h" +#include "dinput.h" + +#include "dinput_private.h" +#include "device_private.h" + +#define MOUSE_HACK + +DEFAULT_DEBUG_CHANNEL(dinput); + +/* Wine mouse driver object instances */ +#define WINE_MOUSE_X_AXIS_INSTANCE 0x0001 +#define WINE_MOUSE_Y_AXIS_INSTANCE 0x0002 +#define WINE_MOUSE_L_BUTTON_INSTANCE 0x0004 +#define WINE_MOUSE_R_BUTTON_INSTANCE 0x0008 +#define WINE_MOUSE_M_BUTTON_INSTANCE 0x0010 + +/* ------------------------------- */ +/* Wine mouse internal data format */ +/* ------------------------------- */ + +/* Constants used to access the offset array */ +#define WINE_MOUSE_X_POSITION 0 +#define WINE_MOUSE_Y_POSITION 1 +#define WINE_MOUSE_L_POSITION 2 +#define WINE_MOUSE_R_POSITION 3 +#define WINE_MOUSE_M_POSITION 4 + +typedef struct { + LONG lX; + LONG lY; + BYTE rgbButtons[4]; +} Wine_InternalMouseData; + +#define WINE_INTERNALMOUSE_NUM_OBJS 5 + +static DIOBJECTDATAFORMAT Wine_InternalMouseObjectFormat[WINE_INTERNALMOUSE_NUM_OBJS] = { + { &GUID_XAxis, FIELD_OFFSET(Wine_InternalMouseData, lX), + DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS, 0 }, + { &GUID_YAxis, FIELD_OFFSET(Wine_InternalMouseData, lY), + DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS, 0 }, + { &GUID_Button, (FIELD_OFFSET(Wine_InternalMouseData, rgbButtons)) + 0, + DIDFT_MAKEINSTANCE(WINE_MOUSE_L_BUTTON_INSTANCE) | DIDFT_PSHBUTTON, 0 }, + { &GUID_Button, (FIELD_OFFSET(Wine_InternalMouseData, rgbButtons)) + 1, + DIDFT_MAKEINSTANCE(WINE_MOUSE_R_BUTTON_INSTANCE) | DIDFT_PSHBUTTON, 0 }, + { &GUID_Button, (FIELD_OFFSET(Wine_InternalMouseData, rgbButtons)) + 2, + DIDFT_MAKEINSTANCE(WINE_MOUSE_M_BUTTON_INSTANCE) | DIDFT_PSHBUTTON, 0 } +}; + +static DIDATAFORMAT Wine_InternalMouseFormat = { + 0, /* dwSize - unused */ + 0, /* dwObjsize - unused */ + 0, /* dwFlags - unused */ + sizeof(Wine_InternalMouseData), + WINE_INTERNALMOUSE_NUM_OBJS, /* dwNumObjs */ + Wine_InternalMouseObjectFormat +}; + +static ICOM_VTABLE(IDirectInputDevice2A) SysMouseAvt; +static ICOM_VTABLE(IDirectInputDevice7A) SysMouse7Avt; +typedef struct SysMouseAImpl SysMouseAImpl; + +typedef enum { + WARP_NEEDED, /* Warping is needed */ + WARP_STARTED, /* Warping has been done, waiting for the warp event */ + WARP_DONE /* Warping has been done */ +} WARP_STATUS; + +struct SysMouseAImpl +{ + /* IDirectInputDevice2AImpl */ + ICOM_VFIELD(IDirectInputDevice2A); + DWORD ref; + GUID guid; + + IDirectInputAImpl *dinput; + + /* The current data format and the conversion between internal + and external data formats */ + LPDIDATAFORMAT df; + DataFormat *wine_df; + int offset_array[5]; + + /* SysMouseAImpl */ + BYTE absolute; + /* Previous position for relative moves */ + LONG prevX, prevY; + LPMOUSE_EVENT_PROC prev_handler; + HWND win; + DWORD win_centerX, win_centerY; + LPDIDEVICEOBJECTDATA data_queue; + int queue_pos, queue_len; + WARP_STATUS need_warp; + int acquired; + HANDLE hEvent; + CRITICAL_SECTION crit; + + /* This is for mouse reporting. */ + Wine_InternalMouseData m_state; +}; + +static GUID DInput_Wine_Mouse_GUID = { /* 9e573ed8-7734-11d2-8d4a-23903fb6bdf7 */ + 0x9e573ed8, + 0x7734, + 0x11d2, + {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7} +}; + +/* FIXME: This is ugly and not thread safe :/ */ +static IDirectInputDevice2A* current_lock = NULL; + + +static BOOL mousedev_enum_device(DWORD dwDevType, DWORD dwFlags, LPCDIDEVICEINSTANCEA lpddi) +{ + if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_MOUSE)) { + TRACE("Enumerating the Mouse device\n"); + + /* Return mouse */ + lpddi->guidInstance = GUID_SysMouse;/* DInput's GUID */ + lpddi->guidProduct = DInput_Wine_Mouse_GUID; /* Vendor's GUID */ + lpddi->dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_UNKNOWN << 8); + strcpy(lpddi->tszInstanceName, "Mouse"); + strcpy(lpddi->tszProductName, "Wine Mouse"); + + return TRUE; + } + + return FALSE; +} + +static SysMouseAImpl *alloc_device(REFGUID rguid, ICOM_VTABLE(IDirectInputDevice2A) *mvt, IDirectInputAImpl *dinput) +{ + int offset_array[5] = { + FIELD_OFFSET(Wine_InternalMouseData, lX), + FIELD_OFFSET(Wine_InternalMouseData, lY), + FIELD_OFFSET(Wine_InternalMouseData, rgbButtons) + 0, + FIELD_OFFSET(Wine_InternalMouseData, rgbButtons) + 1, + FIELD_OFFSET(Wine_InternalMouseData, rgbButtons) + 2 + }; + SysMouseAImpl* newDevice; + newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysMouseAImpl)); + newDevice->ref = 1; + ICOM_VTBL(newDevice) = mvt; + InitializeCriticalSection(&(newDevice->crit)); + memcpy(&(newDevice->guid),rguid,sizeof(*rguid)); + + /* Per default, Wine uses its internal data format */ + newDevice->df = &Wine_InternalMouseFormat; + memcpy(newDevice->offset_array, offset_array, 5 * sizeof(int)); + newDevice->wine_df = (DataFormat *) HeapAlloc(GetProcessHeap(), 0, sizeof(DataFormat)); + newDevice->wine_df->size = 0; + newDevice->wine_df->internal_format_size = Wine_InternalMouseFormat.dwDataSize; + newDevice->wine_df->dt = NULL; + newDevice->dinput = dinput; + + return newDevice; +} + +static HRESULT mousedev_create_device(IDirectInputAImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev) +{ + if ((IsEqualGUID(&GUID_SysMouse,rguid)) || /* Generic Mouse */ + (IsEqualGUID(&DInput_Wine_Mouse_GUID,rguid))) { /* Wine Mouse */ + if ((riid == NULL) || (IsEqualGUID(&IID_IDirectInputDevice2A,riid)) || (IsEqualGUID(&IID_IDirectInputDevice2A,riid))) { + *pdev=(IDirectInputDeviceA*) alloc_device(rguid, &SysMouseAvt, dinput); + + TRACE("Creating a Mouse device (%p)\n", *pdev); + return DI_OK; + }else if (IsEqualGUID(&IID_IDirectInputDevice7A,riid)) { + *pdev=(IDirectInputDeviceA*) alloc_device(rguid, (ICOM_VTABLE(IDirectInputDevice2A) *) &SysMouse7Avt, dinput); + + TRACE("Creating a Mouse DInput7A device (%p)\n", *pdev); + return DI_OK; + } else + return DIERR_NOINTERFACE; + } + + return DIERR_DEVICENOTREG; +} + +static dinput_device mousedev = { + mousedev_enum_device, + mousedev_create_device +}; + +DECL_GLOBAL_CONSTRUCTOR(mousedev_register) { dinput_register_device(&mousedev); } + +/****************************************************************************** + * SysMouseA (DInput Mouse support) + */ + +/****************************************************************************** + * Release : release the mouse buffer. + */ +static ULONG WINAPI SysMouseAImpl_Release(LPDIRECTINPUTDEVICE2A iface) +{ + ICOM_THIS(SysMouseAImpl,iface); + + This->ref--; + if (This->ref) + return This->ref; + + /* Free the data queue */ + if (This->data_queue != NULL) + HeapFree(GetProcessHeap(),0,This->data_queue); + + /* Install the previous event handler (in case of releasing an acquired + mouse device) */ + if (This->prev_handler != NULL) + MOUSE_Enable(This->prev_handler); + DeleteCriticalSection(&(This->crit)); + + /* Free the DataFormat */ + if (This->df != &(Wine_InternalMouseFormat)) { + HeapFree(GetProcessHeap(), 0, This->df->rgodf); + HeapFree(GetProcessHeap(), 0, This->df); + } + + HeapFree(GetProcessHeap(),0,This); + return 0; +} + + +/****************************************************************************** + * SetCooperativeLevel : store the window in which we will do our + * grabbing. + */ +static HRESULT WINAPI SysMouseAImpl_SetCooperativeLevel( + LPDIRECTINPUTDEVICE2A iface,HWND hwnd,DWORD dwflags +) +{ + ICOM_THIS(SysMouseAImpl,iface); + + TRACE("(this=%p,0x%08lx,0x%08lx)\n",This,(DWORD)hwnd,dwflags); + + if (TRACE_ON(dinput)) + _dump_cooperativelevel_DI(dwflags); + + /* Store the window which asks for the mouse */ + This->win = hwnd; + + return 0; +} + + +/****************************************************************************** + * SetDataFormat : the application can choose the format of the data + * the device driver sends back with GetDeviceState. + * + * For the moment, only the "standard" configuration (c_dfDIMouse) is supported + * in absolute and relative mode. + */ +static HRESULT WINAPI SysMouseAImpl_SetDataFormat( + LPDIRECTINPUTDEVICE2A iface,LPCDIDATAFORMAT df +) +{ + ICOM_THIS(SysMouseAImpl,iface); + int i; + + TRACE("(this=%p,%p)\n",This,df); + + TRACE("(df.dwSize=%ld)\n",df->dwSize); + TRACE("(df.dwObjsize=%ld)\n",df->dwObjSize); + TRACE("(df.dwFlags=0x%08lx)\n",df->dwFlags); + TRACE("(df.dwDataSize=%ld)\n",df->dwDataSize); + TRACE("(df.dwNumObjs=%ld)\n",df->dwNumObjs); + + for (i=0;idwNumObjs;i++) { + + TRACE("df.rgodf[%d].guid %s (%p)\n",i, debugstr_guid(df->rgodf[i].pguid), df->rgodf[i].pguid); + TRACE("df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs); + TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType)); + TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags); + } + + /* Check if the mouse is in absolute or relative mode */ + if (df->dwFlags == DIDF_ABSAXIS) + This->absolute = 1; + else if (df->dwFlags == DIDF_RELAXIS) + This->absolute = 0; + else + ERR("Neither absolute nor relative flag set."); + + /* Store the new data format */ + This->df = HeapAlloc(GetProcessHeap(),0,df->dwSize); + memcpy(This->df, df, df->dwSize); + This->df->rgodf = HeapAlloc(GetProcessHeap(),0,df->dwNumObjs*df->dwObjSize); + memcpy(This->df->rgodf,df->rgodf,df->dwNumObjs*df->dwObjSize); + + /* Prepare all the data-conversion filters */ + This->wine_df = create_DataFormat(&(Wine_InternalMouseFormat), df, This->offset_array); + + return 0; +} + +/* Our private mouse event handler */ +static void WINAPI dinput_mouse_event( DWORD dwFlags, DWORD dx, DWORD dy, + DWORD cButtons, DWORD dwExtraInfo ) +{ + long posX = -1, posY = -1; + DWORD keyState, xtime, extra; + SysMouseAImpl* This = (SysMouseAImpl*) current_lock; + + EnterCriticalSection(&(This->crit)); + /* Mouse moved -> send event if asked */ + if (This->hEvent) + SetEvent(This->hEvent); + + if ( !IsBadReadPtr( (LPVOID)dwExtraInfo, sizeof(WINE_MOUSEEVENT) ) + && ((WINE_MOUSEEVENT *)dwExtraInfo)->magic == WINE_MOUSEEVENT_MAGIC ) { + WINE_MOUSEEVENT *wme = (WINE_MOUSEEVENT *)dwExtraInfo; + keyState = wme->keyState; + xtime = wme->time; + extra = (DWORD)wme->hWnd; + + if (dwFlags & MOUSEEVENTF_MOVE) { + if (dwFlags & MOUSEEVENTF_ABSOLUTE) { + posX = (dx * GetSystemMetrics(SM_CXSCREEN)) >> 16; + posY = (dy * GetSystemMetrics(SM_CYSCREEN)) >> 16; + + if (This->absolute) { + if (posX != This->prevX) + GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], posX, xtime, 0); + if (posY != This->prevY) + GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], posY, xtime, 0); + } else { + /* Now, warp handling */ + if ((This->need_warp == WARP_STARTED) && + (posX == This->win_centerX) && (posX == This->win_centerX)) { + /* Warp has been done... */ + This->need_warp = WARP_DONE; + LeaveCriticalSection(&(This->crit)); + return; + } + + /* Relative mouse input with absolute mouse event : the real fun starts here... */ + if ((This->need_warp == WARP_NEEDED) || + (This->need_warp == WARP_STARTED)) { + if (posX != This->prevX) + GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], posX - This->prevX, xtime, (This->dinput->evsequence)++); + if (posY != This->prevY) + GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], posY - This->prevY, xtime, (This->dinput->evsequence)++); + } else { + /* This is the first time the event handler has been called after a + GetData of GetState. */ + if (posX != This->win_centerX) { + GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], posX - This->win_centerX, xtime, (This->dinput->evsequence)++); + This->need_warp = WARP_NEEDED; + } + + if (posY != This->win_centerY) { + GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], posY - This->win_centerY, xtime, (This->dinput->evsequence)++); + This->need_warp = WARP_NEEDED; + } + } + } + + This->prevX = posX; + This->prevY = posY; + + if (This->absolute) { + This->m_state.lX = posX; + This->m_state.lY = posY; + } else { + This->m_state.lX = posX - This->win_centerX; + This->m_state.lY = posY - This->win_centerY; + } + } else { + /* Mouse reporting is in relative mode */ + posX = (long) dx; + posY = (long) dy; + + if (This->absolute) { + long aposX, aposY; + + aposX = This->m_state.lX + posX; + if (aposX < 0) + aposX = 0; + if (aposX >= GetSystemMetrics(SM_CXSCREEN)) + aposX = GetSystemMetrics(SM_CXSCREEN); + + aposY = This->m_state.lY + posY; + if (aposY < 0) + aposY = 0; + if (aposY >= GetSystemMetrics(SM_CYSCREEN)) + aposY = GetSystemMetrics(SM_CYSCREEN); + + if (posX != 0) + GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], aposX, xtime, (This->dinput->evsequence)++); + if (posY != 0) + GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], aposY, xtime, (This->dinput->evsequence)++); + + This->m_state.lX = aposX; + This->m_state.lY = aposY; + } else { + if (posX != 0) + GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], posX, xtime, (This->dinput->evsequence)++); + if (posY != 0) + GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], posY, xtime, (This->dinput->evsequence)++); + + This->m_state.lX = posX; + This->m_state.lY = posY; + } + } + } + } else { + ERR("Mouse event not supported...\n"); + LeaveCriticalSection(&(This->crit)); + return ; + } + + if (TRACE_ON(dinput)) { + if (dwFlags & MOUSEEVENTF_MOVE) + TRACE(" %ld %ld (%s)", posX, posY, + (dwFlags & MOUSEEVENTF_ABSOLUTE ? "abs" : "rel")); + + if ( dwFlags & MOUSEEVENTF_LEFTDOWN ) DPRINTF(" LD "); + if ( dwFlags & MOUSEEVENTF_LEFTUP ) DPRINTF(" LU "); + + if ( dwFlags & MOUSEEVENTF_RIGHTDOWN ) DPRINTF(" RD "); + if ( dwFlags & MOUSEEVENTF_RIGHTUP ) DPRINTF(" RU "); + + if ( dwFlags & MOUSEEVENTF_MIDDLEDOWN ) DPRINTF(" MD "); + if ( dwFlags & MOUSEEVENTF_MIDDLEUP ) DPRINTF(" MU "); + + if (!(This->absolute)) DPRINTF(" W=%d ", This->need_warp); + + DPRINTF("\n"); + } + + + if ( dwFlags & MOUSEEVENTF_LEFTDOWN ) { + GEN_EVENT(This->offset_array[WINE_MOUSE_L_POSITION], 0xFF, xtime, (This->dinput->evsequence)++); + This->m_state.rgbButtons[0] = 0xFF; + } + if ( dwFlags & MOUSEEVENTF_LEFTUP ) { + GEN_EVENT(This->offset_array[WINE_MOUSE_L_POSITION], 0x00, xtime, (This->dinput->evsequence)++); + This->m_state.rgbButtons[0] = 0x00; + } + if ( dwFlags & MOUSEEVENTF_RIGHTDOWN ) { + GEN_EVENT(This->offset_array[WINE_MOUSE_R_POSITION], 0xFF, xtime, (This->dinput->evsequence)++); + This->m_state.rgbButtons[1] = 0xFF; + } + if ( dwFlags & MOUSEEVENTF_RIGHTUP ) { + GEN_EVENT(This->offset_array[WINE_MOUSE_R_POSITION], 0x00, xtime, (This->dinput->evsequence)++); + This->m_state.rgbButtons[1] = 0x00; + } + if ( dwFlags & MOUSEEVENTF_MIDDLEDOWN ) { + GEN_EVENT(This->offset_array[WINE_MOUSE_M_POSITION], 0xFF, xtime, (This->dinput->evsequence)++); + This->m_state.rgbButtons[2] = 0xFF; + } + if ( dwFlags & MOUSEEVENTF_MIDDLEUP ) { + GEN_EVENT(This->offset_array[WINE_MOUSE_M_POSITION], 0x00, xtime, (This->dinput->evsequence)++); + This->m_state.rgbButtons[2] = 0x00; + } + + TRACE("(X: %ld - Y: %ld L: %02x M: %02x R: %02x)\n", + This->m_state.lX, This->m_state.lY, + This->m_state.rgbButtons[0], This->m_state.rgbButtons[2], This->m_state.rgbButtons[1]); + + LeaveCriticalSection(&(This->crit)); +} + + +/****************************************************************************** + * Acquire : gets exclusive control of the mouse + */ +static HRESULT WINAPI SysMouseAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface) +{ + ICOM_THIS(SysMouseAImpl,iface); + RECT rect; + + TRACE("(this=%p)\n",This); + + if (This->acquired == 0) { + POINT point; + + /* This stores the current mouse handler. */ + This->prev_handler = mouse_event; + + /* Store (in a global variable) the current lock */ + current_lock = (IDirectInputDevice2A*)This; + + /* Init the mouse state */ + if (This->absolute) { + This->m_state.lX = PosX; + This->m_state.lY = PosY; + + This->prevX = PosX; + This->prevY = PosY; + } else { + This->m_state.lX = 0; + This->m_state.lY = 0; + } + This->m_state.rgbButtons[0] = (MouseButtonsStates[0] ? 0xFF : 0x00); + This->m_state.rgbButtons[1] = (MouseButtonsStates[1] ? 0xFF : 0x00); + This->m_state.rgbButtons[2] = (MouseButtonsStates[2] ? 0xFF : 0x00); + + /* Install our own mouse event handler */ + MOUSE_Enable(dinput_mouse_event); + + /* Get the window dimension and find the center */ + GetWindowRect(This->win, &rect); + This->win_centerX = (rect.right - rect.left) / 2; + This->win_centerY = (rect.bottom - rect.top ) / 2; + + /* Warp the mouse to the center of the window */ + if (This->absolute == 0) { + TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY); + point.x = This->win_centerX; + point.y = This->win_centerY; + MapWindowPoints(This->win, HWND_DESKTOP, &point, 1); + USER_Driver.pMoveCursor( point.x, point.y ); +#ifdef MOUSE_HACK + This->need_warp = WARP_DONE; +#else + This->need_warp = WARP_STARTED; +#endif + } + + This->acquired = 1; + } + return DI_OK; +} + +/****************************************************************************** + * Unacquire : frees the mouse + */ +static HRESULT WINAPI SysMouseAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface) +{ + ICOM_THIS(SysMouseAImpl,iface); + + TRACE("(this=%p)\n",This); + + if (This->acquired) + { + /* Reinstall previous mouse event handler */ + MOUSE_Enable(This->prev_handler); + This->prev_handler = NULL; + + /* No more locks */ + current_lock = NULL; + + /* Unacquire device */ + This->acquired = 0; + } + else + ERR("Unacquiring a not-acquired device !!!\n"); + + return DI_OK; +} + +/****************************************************************************** + * GetDeviceState : returns the "state" of the mouse. + * + * For the moment, only the "standard" return structure (DIMOUSESTATE) is + * supported. + */ +static HRESULT WINAPI SysMouseAImpl_GetDeviceState( + LPDIRECTINPUTDEVICE2A iface,DWORD len,LPVOID ptr +) { + ICOM_THIS(SysMouseAImpl,iface); + + EnterCriticalSection(&(This->crit)); + TRACE("(this=%p,0x%08lx,%p): \n",This,len,ptr); + + /* Copy the current mouse state */ + fill_DataFormat(ptr, &(This->m_state), This->wine_df); + + /* Initialize the buffer when in relative mode */ + if (This->absolute == 0) { + This->m_state.lX = 0; + This->m_state.lY = 0; + } + + /* Check if we need to do a mouse warping */ + if (This->need_warp == WARP_NEEDED) { + POINT point; + + TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY); + point.x = This->win_centerX; + point.y = This->win_centerY; + MapWindowPoints(This->win, HWND_DESKTOP, &point, 1); + USER_Driver.pMoveCursor( point.x, point.y ); + +#ifdef MOUSE_HACK + This->need_warp = WARP_DONE; +#else + This->need_warp = WARP_STARTED; +#endif + } + + LeaveCriticalSection(&(This->crit)); + + TRACE("(X: %ld - Y: %ld L: %02x M: %02x R: %02x)\n", + This->m_state.lX, This->m_state.lY, + This->m_state.rgbButtons[0], This->m_state.rgbButtons[2], This->m_state.rgbButtons[1]); + + return 0; +} + +/****************************************************************************** + * GetDeviceState : gets buffered input data. + */ +static HRESULT WINAPI SysMouseAImpl_GetDeviceData(LPDIRECTINPUTDEVICE2A iface, + DWORD dodsize, + LPDIDEVICEOBJECTDATA dod, + LPDWORD entries, + DWORD flags +) { + ICOM_THIS(SysMouseAImpl,iface); + + EnterCriticalSection(&(This->crit)); + TRACE("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx)\n",This,dodsize,*entries,flags); + + if (flags & DIGDD_PEEK) + FIXME("DIGDD_PEEK\n"); + + if (dod == NULL) { + *entries = This->queue_pos; + This->queue_pos = 0; + } else { + /* Check for buffer overflow */ + if (This->queue_pos > *entries) { + WARN("Buffer overflow not handled properly yet...\n"); + This->queue_pos = *entries; + } + if (dodsize != sizeof(DIDEVICEOBJECTDATA)) { + ERR("Wrong structure size !\n"); + LeaveCriticalSection(&(This->crit)); + return DIERR_INVALIDPARAM; + } + + if (This->queue_pos) + TRACE("Application retrieving %d event(s).\n", This->queue_pos); + + /* Copy the buffered data into the application queue */ + memcpy(dod, This->data_queue, This->queue_pos * dodsize); + *entries = This->queue_pos; + + /* Reset the event queue */ + This->queue_pos = 0; + } + LeaveCriticalSection(&(This->crit)); + + /* Check if we need to do a mouse warping */ + if (This->need_warp == WARP_NEEDED) { + POINT point; + + TRACE("Warping mouse to %ld - %ld\n", This->win_centerX, This->win_centerY); + point.x = This->win_centerX; + point.y = This->win_centerY; + MapWindowPoints(This->win, HWND_DESKTOP, &point, 1); + + USER_Driver.pMoveCursor( point.x, point.y ); + +#ifdef MOUSE_HACK + This->need_warp = WARP_DONE; +#else + This->need_warp = WARP_STARTED; +#endif + } + return 0; +} + +/****************************************************************************** + * SetProperty : change input device properties + */ +static HRESULT WINAPI SysMouseAImpl_SetProperty(LPDIRECTINPUTDEVICE2A iface, + REFGUID rguid, + LPCDIPROPHEADER ph) +{ + ICOM_THIS(SysMouseAImpl,iface); + + TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(rguid),ph); + + if (!HIWORD(rguid)) { + switch ((DWORD)rguid) { + case (DWORD) DIPROP_BUFFERSIZE: { + LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph; + + TRACE("buffersize = %ld\n",pd->dwData); + + This->data_queue = (LPDIDEVICEOBJECTDATA)HeapAlloc(GetProcessHeap(),0, + pd->dwData * sizeof(DIDEVICEOBJECTDATA)); + This->queue_pos = 0; + This->queue_len = pd->dwData; + break; + } + case (DWORD) DIPROP_AXISMODE: { + LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph; + This->absolute = !(pd->dwData); + TRACE("absolute mode: %d\n", This->absolute); + break; + } + default: + FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,debugstr_guid(rguid)); + break; + } + } + + return 0; +} + +/****************************************************************************** + * GetProperty : get input device properties + */ +static HRESULT WINAPI SysMouseAImpl_GetProperty(LPDIRECTINPUTDEVICE2A iface, + REFGUID rguid, + LPDIPROPHEADER pdiph) +{ + ICOM_THIS(SysMouseAImpl,iface); + + TRACE("(this=%p,%s,%p): stub!\n", + iface, debugstr_guid(rguid), pdiph); + + if (TRACE_ON(dinput)) + _dump_DIPROPHEADER(pdiph); + + if (!HIWORD(rguid)) { + switch ((DWORD)rguid) { + case (DWORD) DIPROP_BUFFERSIZE: { + LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph; + + TRACE(" return buffersize = %d\n",This->queue_len); + pd->dwData = This->queue_len; + break; + } + + case (DWORD) DIPROP_RANGE: { + LPDIPROPRANGE pr = (LPDIPROPRANGE) pdiph; + + if ((pdiph->dwHow == DIPH_BYID) && + ((pdiph->dwObj == (DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS)) || + (pdiph->dwObj == (DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS)))) { + /* Querying the range of either the X or the Y axis. As I do + not know the range, do as if the range where + unrestricted...*/ + pr->lMin = DIPROPRANGE_NOMIN; + pr->lMax = DIPROPRANGE_NOMAX; + } + + break; + } + + default: + FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,debugstr_guid(rguid)); + break; + } + } + + + return DI_OK; +} + + + +/****************************************************************************** + * SetEventNotification : specifies event to be sent on state change + */ +static HRESULT WINAPI SysMouseAImpl_SetEventNotification(LPDIRECTINPUTDEVICE2A iface, + HANDLE hnd) { + ICOM_THIS(SysMouseAImpl,iface); + + TRACE("(this=%p,0x%08lx)\n",This,(DWORD)hnd); + + This->hEvent = hnd; + + return DI_OK; +} + +/****************************************************************************** + * GetCapabilities : get the device capablitites + */ +static HRESULT WINAPI SysMouseAImpl_GetCapabilities( + LPDIRECTINPUTDEVICE2A iface, + LPDIDEVCAPS lpDIDevCaps) +{ + ICOM_THIS(SysMouseAImpl,iface); + + TRACE("(this=%p,%p)\n",This,lpDIDevCaps); + + if (lpDIDevCaps->dwSize == sizeof(DIDEVCAPS)) { + lpDIDevCaps->dwFlags = DIDC_ATTACHED; + lpDIDevCaps->dwDevType = DIDEVTYPE_MOUSE; + lpDIDevCaps->dwAxes = 2; + lpDIDevCaps->dwButtons = 3; + lpDIDevCaps->dwPOVs = 0; + lpDIDevCaps->dwFFSamplePeriod = 0; + lpDIDevCaps->dwFFMinTimeResolution = 0; + lpDIDevCaps->dwFirmwareRevision = 100; + lpDIDevCaps->dwHardwareRevision = 100; + lpDIDevCaps->dwFFDriverVersion = 0; + } else { + /* DirectX 3.0 */ + FIXME("DirectX 3.0 not supported....\n"); + } + + return DI_OK; +} + + +/****************************************************************************** + * EnumObjects : enumerate the different buttons and axis... + */ +static HRESULT WINAPI SysMouseAImpl_EnumObjects( + LPDIRECTINPUTDEVICE2A iface, + LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback, + LPVOID lpvRef, + DWORD dwFlags) +{ + ICOM_THIS(SysMouseAImpl,iface); + DIDEVICEOBJECTINSTANCEA ddoi; + + TRACE("(this=%p,%p,%p,%08lx)\n", This, lpCallback, lpvRef, dwFlags); + if (TRACE_ON(dinput)) { + DPRINTF(" - flags = "); + _dump_EnumObjects_flags(dwFlags); + DPRINTF("\n"); + } + + /* Only the fields till dwFFMaxForce are relevant */ + ddoi.dwSize = FIELD_OFFSET(DIDEVICEOBJECTINSTANCEA, dwFFMaxForce); + + /* In a mouse, we have : two relative axis and three buttons */ + if ((dwFlags == DIDFT_ALL) || + (dwFlags & DIDFT_AXIS)) { + /* X axis */ + ddoi.guidType = GUID_XAxis; + ddoi.dwOfs = This->offset_array[WINE_MOUSE_X_POSITION]; + ddoi.dwType = DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS; + strcpy(ddoi.tszName, "X-Axis"); + _dump_OBJECTINSTANCEA(&ddoi); + if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK; + + /* Y axis */ + ddoi.guidType = GUID_YAxis; + ddoi.dwOfs = This->offset_array[WINE_MOUSE_Y_POSITION]; + ddoi.dwType = DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS; + strcpy(ddoi.tszName, "Y-Axis"); + _dump_OBJECTINSTANCEA(&ddoi); + if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK; + } + + if ((dwFlags == DIDFT_ALL) || + (dwFlags & DIDFT_BUTTON)) { + ddoi.guidType = GUID_Button; + + /* Left button */ + ddoi.dwOfs = This->offset_array[WINE_MOUSE_L_POSITION]; + ddoi.dwType = DIDFT_MAKEINSTANCE(WINE_MOUSE_L_BUTTON_INSTANCE) | DIDFT_PSHBUTTON; + strcpy(ddoi.tszName, "Left-Button"); + _dump_OBJECTINSTANCEA(&ddoi); + if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK; + + /* Right button */ + ddoi.dwOfs = This->offset_array[WINE_MOUSE_R_POSITION]; + ddoi.dwType = DIDFT_MAKEINSTANCE(WINE_MOUSE_R_BUTTON_INSTANCE) | DIDFT_PSHBUTTON; + strcpy(ddoi.tszName, "Right-Button"); + _dump_OBJECTINSTANCEA(&ddoi); + if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK; + + /* Middle button */ + ddoi.dwOfs = This->offset_array[WINE_MOUSE_M_POSITION]; + ddoi.dwType = DIDFT_MAKEINSTANCE(WINE_MOUSE_M_BUTTON_INSTANCE) | DIDFT_PSHBUTTON; + strcpy(ddoi.tszName, "Middle-Button"); + _dump_OBJECTINSTANCEA(&ddoi); + if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK; + } + + return DI_OK; +} + + +static ICOM_VTABLE(IDirectInputDevice2A) SysMouseAvt = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + IDirectInputDevice2AImpl_QueryInterface, + IDirectInputDevice2AImpl_AddRef, + SysMouseAImpl_Release, + SysMouseAImpl_GetCapabilities, + SysMouseAImpl_EnumObjects, + SysMouseAImpl_GetProperty, + SysMouseAImpl_SetProperty, + SysMouseAImpl_Acquire, + SysMouseAImpl_Unacquire, + SysMouseAImpl_GetDeviceState, + SysMouseAImpl_GetDeviceData, + SysMouseAImpl_SetDataFormat, + SysMouseAImpl_SetEventNotification, + SysMouseAImpl_SetCooperativeLevel, + IDirectInputDevice2AImpl_GetObjectInfo, + IDirectInputDevice2AImpl_GetDeviceInfo, + IDirectInputDevice2AImpl_RunControlPanel, + IDirectInputDevice2AImpl_Initialize, + IDirectInputDevice2AImpl_CreateEffect, + IDirectInputDevice2AImpl_EnumEffects, + IDirectInputDevice2AImpl_GetEffectInfo, + IDirectInputDevice2AImpl_GetForceFeedbackState, + IDirectInputDevice2AImpl_SendForceFeedbackCommand, + IDirectInputDevice2AImpl_EnumCreatedEffectObjects, + IDirectInputDevice2AImpl_Escape, + IDirectInputDevice2AImpl_Poll, + IDirectInputDevice2AImpl_SendDeviceData, +}; + +#if !defined(__STRICT_ANSI__) && defined(__GNUC__) +# define XCAST(fun) (typeof(SysMouse7Avt.fn##fun)) +#else +# define XCAST(fun) (void*) +#endif + +static ICOM_VTABLE(IDirectInputDevice7A) SysMouse7Avt = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + XCAST(QueryInterface)IDirectInputDevice2AImpl_QueryInterface, + XCAST(AddRef)IDirectInputDevice2AImpl_AddRef, + XCAST(Release)SysMouseAImpl_Release, + XCAST(GetCapabilities)SysMouseAImpl_GetCapabilities, + XCAST(EnumObjects)SysMouseAImpl_EnumObjects, + XCAST(GetProperty)SysMouseAImpl_GetProperty, + XCAST(SetProperty)SysMouseAImpl_SetProperty, + XCAST(Acquire)SysMouseAImpl_Acquire, + XCAST(Unacquire)SysMouseAImpl_Unacquire, + XCAST(GetDeviceState)SysMouseAImpl_GetDeviceState, + XCAST(GetDeviceData)SysMouseAImpl_GetDeviceData, + XCAST(SetDataFormat)SysMouseAImpl_SetDataFormat, + XCAST(SetEventNotification)SysMouseAImpl_SetEventNotification, + XCAST(SetCooperativeLevel)SysMouseAImpl_SetCooperativeLevel, + XCAST(GetObjectInfo)IDirectInputDevice2AImpl_GetObjectInfo, + XCAST(GetDeviceInfo)IDirectInputDevice2AImpl_GetDeviceInfo, + XCAST(RunControlPanel)IDirectInputDevice2AImpl_RunControlPanel, + XCAST(Initialize)IDirectInputDevice2AImpl_Initialize, + XCAST(CreateEffect)IDirectInputDevice2AImpl_CreateEffect, + XCAST(EnumEffects)IDirectInputDevice2AImpl_EnumEffects, + XCAST(GetEffectInfo)IDirectInputDevice2AImpl_GetEffectInfo, + XCAST(GetForceFeedbackState)IDirectInputDevice2AImpl_GetForceFeedbackState, + XCAST(SendForceFeedbackCommand)IDirectInputDevice2AImpl_SendForceFeedbackCommand, + XCAST(EnumCreatedEffectObjects)IDirectInputDevice2AImpl_EnumCreatedEffectObjects, + XCAST(Escape)IDirectInputDevice2AImpl_Escape, + XCAST(Poll)IDirectInputDevice2AImpl_Poll, + XCAST(SendDeviceData)IDirectInputDevice2AImpl_SendDeviceData, + IDirectInputDevice7AImpl_EnumEffectsInFile, + IDirectInputDevice7AImpl_WriteEffectToFile +}; + +#undef XCAST diff --git a/include/dinput.h b/include/dinput.h index a5a6846c4ba..42a8db6feef 100644 --- a/include/dinput.h +++ b/include/dinput.h @@ -62,6 +62,7 @@ typedef struct IDirectInput2A IDirectInput2A,*LPDIRECTINPUT2A; typedef struct IDirectInput7A IDirectInput7A,*LPDIRECTINPUT7A; typedef struct IDirectInputDeviceA IDirectInputDeviceA,*LPDIRECTINPUTDEVICEA; typedef struct IDirectInputDevice2A IDirectInputDevice2A,*LPDIRECTINPUTDEVICE2A; +typedef struct IDirectInputDevice7A IDirectInputDevice7A,*LPDIRECTINPUTDEVICE7A; typedef struct IDirectInputEffect IDirectInputEffect,*LPDIRECTINPUTEFFECT; typedef struct SysKeyboardA SysKeyboardA,*LPSYSKEYBOARDA; typedef struct SysMouseA SysMouseA,*LPSYSMOUSEA; @@ -758,6 +759,18 @@ typedef struct DIJOYSTATE2 { #define DIJOFS_BUTTON30 DIJOFS_BUTTON(30) #define DIJOFS_BUTTON31 DIJOFS_BUTTON(31) +/* DInput 7 structures, types */ +typedef struct DIFILEEFFECT { + DWORD dwSize; + GUID GuidEffect; + LPCDIEFFECT lpDiEffect; + CHAR szFriendlyName[MAX_PATH]; +} DIFILEEFFECT, *LPDIFILEEFFECT; + +typedef const DIFILEEFFECT *LPCDIFILEEFFECT; +typedef BOOL CALLBACK (*LPDIENUMEFFECTSINFILECALLBACK)(LPCDIFILEEFFECT , LPVOID); + + /***************************************************************************** * IDirectInputEffect interface */ @@ -895,6 +908,54 @@ ICOM_DEFINE(IDirectInputDevice2A,IDirectInputDeviceA) #define IDirectInputDevice2_Poll(p) ICOM_CALL (Poll,p) #define IDirectInputDevice2_SendDeviceData(p,a,b,c,d) ICOM_CALL4(SendDeviceData,p,a,b,c,d) +/***************************************************************************** + * IDirectInputDevice7A interface + */ +#define ICOM_INTERFACE IDirectInputDevice7A +#define IDirectInputDevice7A_METHODS \ + ICOM_METHOD4(HRESULT,EnumEffectsInFile,LPCSTR,lpszFileName,LPDIENUMEFFECTSINFILECALLBACK,pec,LPVOID,pvRef,DWORD,dwFlags) \ + ICOM_METHOD4(HRESULT,WriteEffectToFile,LPCSTR,lpszFileName,DWORD,dwEntries,LPDIFILEEFFECT,rgDiFileEft,DWORD,dwFlags) +#define IDirectInputDevice7A_IMETHODS \ + IDirectInputDeviceA_IMETHODS \ + IDirectInputDevice2A_METHODS \ + IDirectInputDevice7A_METHODS +ICOM_DEFINE(IDirectInputDevice7A,IDirectInputDevice2A) +#undef ICOM_INTERFACE + +/*** IUnknown methods ***/ +#define IDirectInputDevice7_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b) +#define IDirectInputDevice7_AddRef(p) ICOM_CALL (AddRef,p) +#define IDirectInputDevice7_Release(p) ICOM_CALL (Release,p) +/*** IDirectInputDevice methods ***/ +#define IDirectInputDevice7_GetCapabilities(p,a) ICOM_CALL1(GetCapabilities,p,a) +#define IDirectInputDevice7_EnumObjects(p,a,b,c) ICOM_CALL3(EnumObjects,p,a,b,c) +#define IDirectInputDevice7_GetProperty(p,a,b) ICOM_CALL2(GetProperty,p,a,b) +#define IDirectInputDevice7_SetProperty(p,a,b) ICOM_CALL2(SetProperty,p,a,b) +#define IDirectInputDevice7_Acquire(p) ICOM_CALL (Acquire,p) +#define IDirectInputDevice7_Unacquire(p) ICOM_CALL (Unacquire,p) +#define IDirectInputDevice7_GetDeviceState(p,a,b) ICOM_CALL2(GetDeviceState,p,a,b) +#define IDirectInputDevice7_GetDeviceData(p,a,b,c,d) ICOM_CALL4(GetDeviceData,p,a,b,c,d) +#define IDirectInputDevice7_SetDataFormat(p,a) ICOM_CALL1(SetDataFormat,p,a) +#define IDirectInputDevice7_SetEventNotification(p,a) ICOM_CALL1(SetEventNotification,p,a) +#define IDirectInputDevice7_SetCooperativeLevel(p,a,b) ICOM_CALL2(SetCooperativeLevel,p,a,b) +#define IDirectInputDevice7_GetObjectInfo(p,a,b,c) ICOM_CALL3(GetObjectInfo,p,a,b,c) +#define IDirectInputDevice7_GetDeviceInfo(p,a) ICOM_CALL1(GetDeviceInfo,p,a) +#define IDirectInputDevice7_RunControlPanel(p,a,b) ICOM_CALL2(RunControlPanel,p,a,b) +#define IDirectInputDevice7_Initialize(p,a,b,c) ICOM_CALL3(Initialize,p,a,b,c) +/*** IDirectInputDevice2 methods ***/ +#define IDirectInputDevice7_CreateEffect(p,a,b,c,d) ICOM_CALL4(CreateEffect,p,a,b,c,d) +#define IDirectInputDevice7_EnumEffects(p,a,b,c) ICOM_CALL3(EnumEffects,p,a,b,c) +#define IDirectInputDevice7_GetEffectInfo(p,a,b) ICOM_CALL2(GetEffectInfo,p,a,b) +#define IDirectInputDevice7_GetForceFeedbackState(p,a) ICOM_CALL1(GetForceFeedbackState,p,a) +#define IDirectInputDevice7_SendForceFeedbackCommand(p,a) ICOM_CALL1(SendForceFeedbackCommand,p,a) +#define IDirectInputDevice7_EnumCreatedEffectObjects(p,a,b,c) ICOM_CALL3(EnumCreatedEffectObjects,p,a,b,c) +#define IDirectInputDevice7_Escape(p,a) ICOM_CALL1(Escape,p,a) +#define IDirectInputDevice7_Poll(p) ICOM_CALL (Poll,p) +#define IDirectInputDevice7_SendDeviceData(p,a,b,c,d) ICOM_CALL4(SendDeviceData,p,a,b,c,d) +/*** IDirectInputDevice7 methods ***/ +#define IDirectInputDevice7_EnumEffectsInFile(p,a,b,c,d) ICOM_CALL4(EnumEffectsInFile,p,a,b,c,d) +#define IDirectInputDevice7_WriteEffectToFile(p,a,b,c,d) ICOM_CALL4(WriteEffectToFile,p,a,b,c,d) + /* "Standard" Mouse report... */ typedef struct DIMOUSESTATE { LONG lX;