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