Module: wine Branch: master Commit: ce0c3cdae7e8a3149425989cf6522a438fceeeaf URL: http://source.winehq.org/git/wine.git/?a=commit;h=ce0c3cdae7e8a3149425989cf6...
Author: Vitaliy Margolen wine-patches@kievinfo.com Date: Mon Dec 4 10:54:05 2006 -0700
dinput: Implement [Get|Set]Property and GetDeviceData in base Device object.
Also add queue_event to replace big macro GEN_EVENT.
---
dlls/dinput/device.c | 177 +++++++++++++++++++++++++++++++++++++++--- dlls/dinput/device_private.h | 15 +++- 2 files changed, 176 insertions(+), 16 deletions(-)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c index 105bb02..7d24dfc 100644 --- a/dlls/dinput/device.c +++ b/dlls/dinput/device.c @@ -448,6 +448,35 @@ BOOL DIEnumDevicesCallbackAtoW(LPCDIDEVI }
/****************************************************************************** + * queue_event - add new event to the ring queue + */ + +void queue_event(LPDIRECTINPUTDEVICE8A iface, int ofs, DWORD data, DWORD time, DWORD seq) +{ + IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface; + int next_pos; + + if (!This->queue_len || This->overflow || ofs < 0) return; + + next_pos = (This->queue_head + 1) % This->queue_len; + if (next_pos == This->queue_tail) + { + TRACE(" queue overflowed\n"); + This->overflow = TRUE; + return; + } + + TRACE(" queueing %d at offset %d (queue head %d / size %d)\n", + data, ofs, This->queue_head, This->queue_len); + + This->data_queue[This->queue_head].dwOfs = ofs; + This->data_queue[This->queue_head].dwData = data; + This->data_queue[This->queue_head].dwTimeStamp = time; + This->data_queue[This->queue_head].dwSequence = seq; + This->queue_head = next_pos; +} + +/****************************************************************************** * Acquire */
@@ -459,6 +488,8 @@ HRESULT WINAPI IDirectInputDevice2AImpl_ EnterCriticalSection(&This->crit); res = This->acquired ? S_FALSE : DI_OK; This->acquired = 1; + if (res == DI_OK) + This->queue_head = This->queue_tail = This->overflow = 0; LeaveCriticalSection(&This->crit);
return res; @@ -558,10 +589,15 @@ ULONG WINAPI IDirectInputDevice2AImpl_Re { IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface; ULONG ref; + ref = InterlockedDecrement(&(This->ref)); - if (ref == 0) - HeapFree(GetProcessHeap(),0,This); - return ref; + if (ref) return ref; + + DeleteCriticalSection(&This->crit); + HeapFree(GetProcessHeap(), 0, This->data_queue); + HeapFree(GetProcessHeap(), 0, This); + + return DI_OK; }
HRESULT WINAPI IDirectInputDevice2AImpl_QueryInterface( @@ -675,17 +711,81 @@ HRESULT WINAPI IDirectInputDevice2WImpl_ return DI_OK; }
+/****************************************************************************** + * GetProperty + */ + HRESULT WINAPI IDirectInputDevice2AImpl_GetProperty( - LPDIRECTINPUTDEVICE8A iface, - REFGUID rguid, - LPDIPROPHEADER pdiph) + LPDIRECTINPUTDEVICE8A iface, REFGUID rguid, LPDIPROPHEADER pdiph) { - FIXME("(this=%p,%s,%p): stub!\n", - iface, debugstr_guid(rguid), pdiph); - - if (TRACE_ON(dinput)) - _dump_DIPROPHEADER(pdiph); - + IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface; + + TRACE("(%p) %s,%p\n", iface, debugstr_guid(rguid), pdiph); + _dump_DIPROPHEADER(pdiph); + + if (HIWORD(rguid)) return DI_OK; + + switch (LOWORD(rguid)) + { + case (DWORD) DIPROP_BUFFERSIZE: + { + LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph; + + if (pdiph->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM; + + pd->dwData = This->queue_len; + TRACE("buffersize = %d\n", pd->dwData); + break; + } + default: + WARN("Unknown property %s\n", debugstr_guid(rguid)); + break; + } + + return DI_OK; +} + +/****************************************************************************** + * SetProperty + */ + +HRESULT WINAPI IDirectInputDevice2AImpl_SetProperty( + LPDIRECTINPUTDEVICE8A iface, REFGUID rguid, LPCDIPROPHEADER pdiph) +{ + IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface; + + TRACE("(%p) %s,%p\n", iface, debugstr_guid(rguid), pdiph); + _dump_DIPROPHEADER(pdiph); + + if (HIWORD(rguid)) return DI_OK; + + switch (LOWORD(rguid)) + { + case (DWORD) DIPROP_BUFFERSIZE: + { + LPCDIPROPDWORD pd = (LPCDIPROPDWORD)pdiph; + + if (pdiph->dwSize != sizeof(DIPROPDWORD)) return DIERR_INVALIDPARAM; + if (This->acquired) return DIERR_ACQUIRED; + + TRACE("buffersize = %d\n", pd->dwData); + + EnterCriticalSection(&This->crit); + HeapFree(GetProcessHeap(), 0, This->data_queue); + + This->data_queue = !pd->dwData ? NULL : HeapAlloc(GetProcessHeap(), 0, + pd->dwData * sizeof(DIDEVICEOBJECTDATA)); + This->queue_head = This->queue_tail = This->overflow = 0; + This->queue_len = pd->dwData; + + LeaveCriticalSection(&This->crit); + break; + } + default: + WARN("Unknown property %s\n", debugstr_guid(rguid)); + return DIERR_UNSUPPORTED; + } + return DI_OK; }
@@ -713,6 +813,59 @@ HRESULT WINAPI IDirectInputDevice2WImpl_ return DI_OK; }
+HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceData( + LPDIRECTINPUTDEVICE8A iface, DWORD dodsize, LPDIDEVICEOBJECTDATA dod, + LPDWORD entries, DWORD flags) +{ + IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface; + HRESULT ret = DI_OK; + int len; + + TRACE("(%p) %p -> %p(%d) x%d, 0x%08x\n", + This, dod, entries, entries ? *entries : 0, dodsize, flags); + + if (!This->acquired) + return DIERR_NOTACQUIRED; + if (!This->queue_len) + return DIERR_NOTBUFFERED; + if (dodsize < sizeof(DIDEVICEOBJECTDATA_DX3)) + return DIERR_INVALIDPARAM; + + IDirectInputDevice2_Poll(iface); + EnterCriticalSection(&This->crit); + + len = This->queue_head - This->queue_tail; + if (len < 0) len += This->queue_len; + + if ((*entries != INFINITE) && (len > *entries)) len = *entries; + + if (dod) + { + int i; + for (i = 0; i < len; i++) + { + int n = (This->queue_tail + i) % This->queue_len; + memcpy((char *)dod + dodsize * i, This->data_queue + n, dodsize); + } + } + *entries = len; + + if (This->overflow) + ret = DI_BUFFEROVERFLOW; + + if (!(flags & DIGDD_PEEK)) + { + /* Advance reading position */ + This->queue_tail = (This->queue_tail + len) % This->queue_len; + This->overflow = FALSE; + } + + LeaveCriticalSection(&This->crit); + + TRACE("Returning %d events queued\n", *entries); + return ret; +} + HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceInfo( LPDIRECTINPUTDEVICE8A iface, LPDIDEVICEINSTANCEA pdidi) diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h index 212e598..c32b4f5 100644 --- a/dlls/dinput/device_private.h +++ b/dlls/dinput/device_private.h @@ -38,6 +38,12 @@ struct IDirectInputDevice2AImpl DWORD dwCoopLevel; HWND win; int acquired; + + LPDIDEVICEOBJECTDATA data_queue; /* buffer for 'GetDeviceData'. */ + int queue_len; /* size of the queue - set in 'SetProperty' */ + int queue_head; /* position to write new event into queue */ + int queue_tail; /* next event to read from queue */ + BOOL overflow; /* return DI_BUFFEROVERFLOW in 'GetDeviceData' */ };
/* Routines to do DataFormat / WineFormat conversions */ @@ -56,6 +62,7 @@ typedef struct { extern void fill_DataFormat(void *out, const void *in, DataFormat *df) ; extern DataFormat *create_DataFormat(const DIDATAFORMAT *wine_format, LPCDIDATAFORMAT asked_format, int *offset) ; extern void release_DataFormat(DataFormat *df) ; +extern void queue_event(LPDIRECTINPUTDEVICE8A iface, int ofs, DWORD data, DWORD time, DWORD seq);
/* Used to fill events in the queue */ #define GEN_EVENT(offset,data,xtime,seq) \ @@ -124,10 +131,8 @@ extern HRESULT WINAPI IDirectInputDevice LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback, LPVOID lpvRef, DWORD dwFlags) ; -extern HRESULT WINAPI IDirectInputDevice2AImpl_GetProperty( - LPDIRECTINPUTDEVICE8A iface, - REFGUID rguid, - LPDIPROPHEADER pdiph) ; +extern HRESULT WINAPI IDirectInputDevice2AImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface, REFGUID rguid, LPDIPROPHEADER pdiph); +extern HRESULT WINAPI IDirectInputDevice2AImpl_SetProperty(LPDIRECTINPUTDEVICE8A iface, REFGUID rguid, LPCDIPROPHEADER pdiph); extern HRESULT WINAPI IDirectInputDevice2AImpl_GetObjectInfo( LPDIRECTINPUTDEVICE8A iface, LPDIDEVICEOBJECTINSTANCEA pdidoi, @@ -137,6 +142,8 @@ extern HRESULT WINAPI IDirectInputDevice LPDIDEVICEOBJECTINSTANCEW pdidoi, DWORD dwObj, DWORD dwHow); +extern HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceData(LPDIRECTINPUTDEVICE8A iface, + DWORD dodsize, LPDIDEVICEOBJECTDATA dod, LPDWORD entries, DWORD flags); extern HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceInfo( LPDIRECTINPUTDEVICE8A iface, LPDIDEVICEINSTANCEA pdidi) ;