Vitaliy Margolen : dinput: Implement [Get|Set]
Property and GetDeviceData in base Device object.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Dec 5 04:51:06 CST 2006
Module: wine
Branch: master
Commit: ce0c3cdae7e8a3149425989cf6522a438fceeeaf
URL: http://source.winehq.org/git/wine.git/?a=commit;h=ce0c3cdae7e8a3149425989cf6522a438fceeeaf
Author: Vitaliy Margolen <wine-patches at 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) ;
More information about the wine-cvs
mailing list