dinput: Keyboard: Use the same event queue mechanism as
mouse.[resend]
Vitaliy Margolen
wine-patch at kievinfo.com
Thu Jul 27 09:19:59 CDT 2006
ChangeLog:
dinput: Keyboard: Use the same event queue mechanism as mouse.
Resend as standalone change.
dlls/dinput/keyboard.c | 214 ++++++++++++++++++++----------------------------
1 files changed, 91 insertions(+), 123 deletions(-)
-------------- next part --------------
c867967624df561480528d1a4c8fd4d78fd2f4ce
diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c
index f6195b1..da246e4 100644
--- a/dlls/dinput/keyboard.c
+++ b/dlls/dinput/keyboard.c
@@ -46,26 +46,23 @@ static const IDirectInputDevice8WVtbl Sy
typedef struct SysKeyboardImpl SysKeyboardImpl;
struct SysKeyboardImpl
{
- const void *lpVtbl;
- LONG ref;
- GUID guid;
-
- IDirectInputImpl* dinput;
-
- HANDLE hEvent;
- /* SysKeyboardAImpl */
- int acquired;
- int buffersize; /* set in 'SetProperty' */
- LPDIDEVICEOBJECTDATA buffer; /* buffer for 'GetDeviceData'.
- Alloc at 'Acquire', Free at
- 'Unacquire' */
- int count; /* number of objects in use in
- 'buffer' */
- int start; /* 'buffer' rotates. This is the
- first in use (if count > 0) */
- BOOL overflow; /* return DI_BUFFEROVERFLOW in
- 'GetDeviceData' */
- CRITICAL_SECTION crit;
+ const void *lpVtbl;
+ LONG ref;
+ GUID guid;
+
+ IDirectInputImpl* dinput;
+
+ HANDLE hEvent;
+ /* SysKeyboardAImpl */
+ int acquired;
+
+ LPDIDEVICEOBJECTDATA data_queue; /* buffer for 'GetDeviceData'. Alloc at
+ 'Acquire', Free at 'Unacquire' */
+ 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' */
+ CRITICAL_SECTION crit;
};
static SysKeyboardImpl* current_lock = NULL;
@@ -81,8 +78,7 @@ static BYTE DInputKeyState[WINE_DINPUT_K
LRESULT CALLBACK KeyboardCallback( int code, WPARAM wparam, LPARAM lparam )
{
SysKeyboardImpl *This = (SysKeyboardImpl *)current_lock;
- BYTE dik_code;
- BOOL down;
+ int dik_code;
KBDLLHOOKSTRUCT *hook = (KBDLLHOOKSTRUCT *)lparam;
BYTE new_diks;
@@ -91,44 +87,24 @@ LRESULT CALLBACK KeyboardCallback( int c
/* returns now if not HC_ACTION */
if (code != HC_ACTION) return CallNextHookEx(0, code, wparam, lparam);
- dik_code = hook->scanCode;
+ dik_code = hook->scanCode & 0xff;
if (hook->flags & LLKHF_EXTENDED) dik_code |= 0x80;
- down = !(hook->flags & LLKHF_UP);
- /** returns now if key event already known */
- new_diks = (down ? 0x80 : 0);
+ new_diks = hook->flags & LLKHF_UP ? 0 : 0x80;
+
+ /* returns now if key event already known */
if (new_diks == DInputKeyState[dik_code])
return CallNextHookEx(0, code, wparam, lparam);
DInputKeyState[dik_code] = new_diks;
TRACE(" setting %02X to %02X\n", dik_code, DInputKeyState[dik_code]);
+ EnterCriticalSection(&This->crit);
+ GEN_EVENT(dik_code, new_diks, hook->time, This->dinput->evsequence++);
+ LeaveCriticalSection(&This->crit);
+
if (This->hEvent) SetEvent(This->hEvent);
- if (This->buffer != NULL)
- {
- int n;
-
- EnterCriticalSection(&(This->crit));
-
- n = (This->start + This->count) % This->buffersize;
-
- This->buffer[n].dwOfs = dik_code;
- This->buffer[n].dwData = down ? 0x80 : 0;
- This->buffer[n].dwTimeStamp = hook->time;
- This->buffer[n].dwSequence = This->dinput->evsequence++;
-
- TRACE("Adding event at offset %d : %ld - %ld - %ld - %ld\n", n,
- This->buffer[n].dwOfs, This->buffer[n].dwData, This->buffer[n].dwTimeStamp, This->buffer[n].dwSequence);
-
- if (This->count == This->buffersize) {
- This->start = ++This->start % This->buffersize;
- This->overflow = TRUE;
- }
- else This->count++;
-
- LeaveCriticalSection(&(This->crit));
- }
return CallNextHookEx(0, code, wparam, lparam);
}
@@ -293,7 +269,7 @@ static ULONG WINAPI SysKeyboardAImpl_Rel
set_dinput_hook(WH_KEYBOARD_LL, NULL);
/* Free the data queue */
- HeapFree(GetProcessHeap(),0,This->buffer);
+ HeapFree(GetProcessHeap(), 0, This->data_queue);
DeleteCriticalSection(&(This->crit));
@@ -320,7 +296,7 @@ static HRESULT WINAPI SysKeyboardAImpl_S
if (This->acquired)
return DIERR_INVALIDPARAM;
- This->buffersize = pd->dwData;
+ This->queue_len = pd->dwData;
break;
}
@@ -351,7 +327,7 @@ static HRESULT WINAPI SysKeyboardAImpl_G
if (This->acquired)
return DIERR_INVALIDPARAM;
- pd->dwData = This->buffersize;
+ pd->dwData = This->queue_len;
break;
}
@@ -399,59 +375,54 @@ static HRESULT WINAPI SysKeyboardAImpl_G
LPDWORD entries,DWORD flags
)
{
- SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
- int ret = DI_OK, i = 0;
-
- TRACE("(this=%p,%ld,%p,%p(%ld)),0x%08lx)\n",
- This,dodsize,dod,entries,entries?*entries:0,flags);
-
- if (This->acquired == 0)
- return DIERR_NOTACQUIRED;
+ SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
+ HRESULT ret = DI_OK;
+ int len;
- if (This->buffer == NULL)
- return DIERR_NOTBUFFERED;
+ TRACE("(%p) %p -> %p(%ld) x%ld, 0x%08lx\n",
+ This, dod, entries, entries ? *entries : 0, dodsize, flags);
- if (dodsize < sizeof(DIDEVICEOBJECTDATA_DX3))
- return DIERR_INVALIDPARAM;
+ if (!This->acquired)
+ return DIERR_NOTACQUIRED;
- MsgWaitForMultipleObjectsEx(0, NULL, 0, QS_ALLINPUT, 0);
+ if (!This->data_queue)
+ return DIERR_NOTBUFFERED;
- EnterCriticalSection(&(This->crit));
+ if (dodsize < sizeof(DIDEVICEOBJECTDATA_DX3))
+ return DIERR_INVALIDPARAM;
- /* Copy item at a time for the case dodsize > sizeof(buffer[n]) */
- while ((i < *entries || *entries == INFINITE) && i < This->count)
- {
- if (dod != NULL)
- {
- int n = (This->start + i) % This->buffersize;
- LPDIDEVICEOBJECTDATA pd
- = (LPDIDEVICEOBJECTDATA)((BYTE *)dod + dodsize * i);
- pd->dwOfs = This->buffer[n].dwOfs;
- pd->dwData = This->buffer[n].dwData;
- pd->dwTimeStamp = This->buffer[n].dwTimeStamp;
- pd->dwSequence = This->buffer[n].dwSequence;
- }
- i++;
- }
+ MsgWaitForMultipleObjectsEx(0, NULL, 0, QS_ALLINPUT, 0);
+ EnterCriticalSection(&This->crit);
- *entries = i;
+ len = ((This->queue_head < This->queue_tail) ? This->queue_len : 0) +
+ This->queue_head - This->queue_tail;
+ if ((*entries != INFINITE) && (len > *entries)) len = *entries;
- if (This->overflow)
- ret = DI_BUFFEROVERFLOW;
+ 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 (!(flags & DIGDD_PEEK))
- {
- /* Empty buffer */
- This->count -= i;
- This->start = (This->start + i) % This->buffersize;
- This->overflow = FALSE;
- }
+ if (This->overflow)
+ ret = DI_BUFFEROVERFLOW;
- LeaveCriticalSection(&(This->crit));
+ if (!(flags & DIGDD_PEEK))
+ {
+ /* Empty buffer */
+ This->queue_tail = (This->queue_tail + len) % This->queue_len;
+ This->overflow = FALSE;
+ }
- TRACE("Returning %ld events queued\n", *entries);
+ LeaveCriticalSection(&This->crit);
- return ret;
+ TRACE("Returning %ld events queued\n", *entries);
+ return ret;
}
static HRESULT WINAPI SysKeyboardAImpl_EnumObjects(
@@ -507,35 +478,32 @@ static HRESULT WINAPI SysKeyboardAImpl_U
static HRESULT WINAPI SysKeyboardAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
{
- SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
+ SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
- TRACE("(this=%p)\n",This);
+ TRACE("(%p)\n",This);
- if (This->acquired)
- return S_FALSE;
+ if (This->acquired) return DI_NOEFFECT;
+ This->acquired = 1;
- This->acquired = 1;
+ if (current_lock != NULL) {
+ FIXME("Not more than one keyboard can be acquired at the same time.\n");
+ SysKeyboardAImpl_Unacquire((LPDIRECTINPUTDEVICE8A)current_lock);
+ }
+ current_lock = This;
- if (current_lock != NULL) {
- FIXME("Not more than one keyboard can be acquired at the same time.\n");
- SysKeyboardAImpl_Unacquire((LPDIRECTINPUTDEVICE8A)current_lock);
- }
-
- current_lock = This;
-
- if (This->buffersize > 0) {
- This->buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- This->buffersize * sizeof(*(This->buffer)));
- This->start = 0;
- This->count = 0;
- This->overflow = FALSE;
- } else {
- This->buffer = NULL;
- }
+ if (This->queue_len > 0)
+ {
+ This->data_queue = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ This->queue_len * sizeof(*(This->data_queue)));
+ This->queue_head = 0;
+ This->queue_tail = 0;
+ This->overflow = FALSE;
+ } else
+ This->data_queue = NULL;
- set_dinput_hook(WH_KEYBOARD_LL, KeyboardCallback);
+ set_dinput_hook(WH_KEYBOARD_LL, KeyboardCallback);
- return DI_OK;
+ return DI_OK;
}
static HRESULT WINAPI SysKeyboardAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface)
@@ -557,12 +525,12 @@ static HRESULT WINAPI SysKeyboardAImpl_U
/* Unacquire device */
This->acquired = 0;
- if (This->buffersize >= 0) {
- HeapFree(GetProcessHeap(), 0, This->buffer);
- This->buffer = NULL;
- }
+ if (This->queue_len >= 0) {
+ HeapFree(GetProcessHeap(), 0, This->data_queue);
+ This->data_queue = NULL;
+ }
- return DI_OK;
+ return DI_OK;
}
static HRESULT WINAPI SysKeyboardAImpl_SetEventNotification(LPDIRECTINPUTDEVICE8A iface,
More information about the wine-patches
mailing list