dinput: Implement [Get|Set]Property and GetDeviceData in base Device object.

Also add queue_event to replace big macro GEN_EVENT.
This commit is contained in:
Vitaliy Margolen 2006-12-04 10:54:05 -07:00 committed by Alexandre Julliard
parent 97419aea80
commit ce0c3cdae7
2 changed files with 176 additions and 16 deletions

View file

@ -447,6 +447,35 @@ BOOL DIEnumDevicesCallbackAtoW(LPCDIDEVICEOBJECTINSTANCEA lpddi, LPVOID lpvRef)
return data->lpCallBack(&ddtmp, data->lpvRef);
}
/******************************************************************************
* 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_Acquire(LPDIRECTINPUTDEVICE8A iface)
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_Release(LPDIRECTINPUTDEVICE8A iface)
{
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_EnumObjects(
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_GetObjectInfo(
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)

View file

@ -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 IDirectInputDevice2WImpl_EnumObjects(
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 IDirectInputDevice2WImpl_GetObjectInfo(LPDIRECTINPUTDEVICE
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) ;