Partial rewrite of the win32 mouse motion handling.
- If the mouse is captured, use ClipCursor() to keep the cursor in the window. - After handling mouse motion event in relative mode, move the cursor back to the window center (similar to other guis).
This commit is contained in:
parent
2f893a76ff
commit
33a633cbd2
@ -92,11 +92,11 @@ struct QueueEvent {
|
||||
QueueEvent* deq_key_event(void);
|
||||
|
||||
static QueueEvent keyevents[SCANCODE_BUFSIZE];
|
||||
static unsigned head=0, tail=0;
|
||||
static unsigned head = 0, tail = 0;
|
||||
static int mouse_button_state = 0;
|
||||
static int ms_xdelta=0, ms_ydelta=0, ms_zdelta=0;
|
||||
static int ms_lastx=0, ms_lasty=0;
|
||||
static int ms_savedx=0, ms_savedy=0;
|
||||
static int ms_xdelta = 0, ms_ydelta = 0, ms_zdelta = 0;
|
||||
static int ms_lastx = 0, ms_lasty = 0;
|
||||
static int ms_savedx = 0, ms_savedy = 0;
|
||||
static BOOL mouseCaptureMode, mouseCaptureNew, mouseToggleReq;
|
||||
static BOOL win32MouseModeAbsXY = 0;
|
||||
static HANDLE workerThread = 0;
|
||||
@ -478,63 +478,50 @@ Bit32u win32_to_bx_key[2][0x100] =
|
||||
VOID CALLBACK MyTimer(HWND,UINT,UINT,DWORD);
|
||||
#endif
|
||||
|
||||
static void processMouseXY(int x, int y, int z, int windows_state, int implied_state_change)
|
||||
{
|
||||
int bx_state;
|
||||
int old_bx_state;
|
||||
EnterCriticalSection(&stInfo.mouseCS);
|
||||
bx_state=((windows_state & MK_LBUTTON) ? 1 : 0) + ((windows_state & MK_RBUTTON) ? 2 : 0) +
|
||||
((windows_state & MK_MBUTTON) ? 4 : 0);
|
||||
old_bx_state=bx_state ^ implied_state_change;
|
||||
if (old_bx_state!=mouse_button_state)
|
||||
{
|
||||
/* Make up for missing message */
|
||||
BX_INFO(("&&&missing mouse state change"));
|
||||
EnterCriticalSection(&stInfo.keyCS);
|
||||
enq_mouse_event();
|
||||
mouse_button_state=old_bx_state;
|
||||
enq_key_event(mouse_button_state, MOUSE_PRESSED);
|
||||
LeaveCriticalSection(&stInfo.keyCS);
|
||||
}
|
||||
ms_ydelta=ms_savedy-y;
|
||||
ms_xdelta=x-ms_savedx;
|
||||
ms_zdelta=z;
|
||||
ms_lastx=x;
|
||||
ms_lasty=y;
|
||||
if (bx_state!=mouse_button_state)
|
||||
{
|
||||
EnterCriticalSection(&stInfo.keyCS);
|
||||
enq_mouse_event();
|
||||
mouse_button_state=bx_state;
|
||||
enq_key_event(mouse_button_state, MOUSE_PRESSED);
|
||||
LeaveCriticalSection(&stInfo.keyCS);
|
||||
}
|
||||
LeaveCriticalSection(&stInfo.mouseCS);
|
||||
}
|
||||
|
||||
static void resetDelta()
|
||||
{
|
||||
EnterCriticalSection(&stInfo.mouseCS);
|
||||
ms_savedx=ms_lastx;
|
||||
ms_savedy=ms_lasty;
|
||||
ms_ydelta=ms_xdelta=ms_zdelta=0;
|
||||
LeaveCriticalSection(&stInfo.mouseCS);
|
||||
}
|
||||
|
||||
static void cursorWarped()
|
||||
{
|
||||
POINT pt = { 0, 0 };
|
||||
|
||||
ClientToScreen(stInfo.simWnd, &pt);
|
||||
SetCursorPos(pt.x + stretched_x/2, pt.y + stretched_y/2);
|
||||
SetCursorPos(pt.x + stretched_x / 2, pt.y + stretched_y / 2);
|
||||
EnterCriticalSection(&stInfo.mouseCS);
|
||||
EnterCriticalSection(&stInfo.keyCS);
|
||||
enq_mouse_event();
|
||||
LeaveCriticalSection(&stInfo.keyCS);
|
||||
ms_lastx=stretched_x/2;
|
||||
ms_lasty=stretched_y/2;
|
||||
ms_savedx=ms_lastx;
|
||||
ms_savedy=ms_lasty;
|
||||
ms_savedx = stretched_x / 2;
|
||||
ms_savedy = stretched_y / 2;
|
||||
LeaveCriticalSection(&stInfo.mouseCS);
|
||||
}
|
||||
|
||||
static void processMouseXY(int x, int y, int z, int windows_state, int implied_state_change)
|
||||
{
|
||||
int bx_state;
|
||||
int old_bx_state;
|
||||
EnterCriticalSection(&stInfo.mouseCS);
|
||||
bx_state = ((windows_state & MK_LBUTTON) ? 1 : 0) + ((windows_state & MK_RBUTTON) ? 2 : 0) +
|
||||
((windows_state & MK_MBUTTON) ? 4 : 0);
|
||||
old_bx_state = bx_state ^ implied_state_change;
|
||||
if (old_bx_state != mouse_button_state) {
|
||||
/* Make up for missing message */
|
||||
BX_INFO(("&&&missing mouse state change"));
|
||||
EnterCriticalSection(&stInfo.keyCS);
|
||||
enq_mouse_event();
|
||||
mouse_button_state = old_bx_state;
|
||||
enq_key_event(mouse_button_state, MOUSE_PRESSED);
|
||||
LeaveCriticalSection(&stInfo.keyCS);
|
||||
}
|
||||
ms_ydelta = ms_savedy - y;
|
||||
ms_xdelta = x - ms_savedx;
|
||||
ms_zdelta = z;
|
||||
ms_lastx = x;
|
||||
ms_lasty = y;
|
||||
if (bx_state!=mouse_button_state) {
|
||||
EnterCriticalSection(&stInfo.keyCS);
|
||||
enq_mouse_event();
|
||||
mouse_button_state = bx_state;
|
||||
enq_key_event(mouse_button_state, MOUSE_PRESSED);
|
||||
LeaveCriticalSection(&stInfo.keyCS);
|
||||
}
|
||||
if (mouseCaptureMode && !win32MouseModeAbsXY) {
|
||||
cursorWarped();
|
||||
}
|
||||
LeaveCriticalSection(&stInfo.mouseCS);
|
||||
}
|
||||
|
||||
@ -955,7 +942,9 @@ DWORD WINAPI UIThread(LPVOID)
|
||||
SetFocus(stInfo.simWnd);
|
||||
|
||||
ShowCursor(!mouseCaptureMode);
|
||||
cursorWarped();
|
||||
if (mouseCaptureMode && !win32MouseModeAbsXY) {
|
||||
cursorWarped();
|
||||
}
|
||||
|
||||
hdc = GetDC(stInfo.simWnd);
|
||||
MemoryBitmap = CreateCompatibleBitmap(hdc, win32_max_xres, win32_max_yres);
|
||||
@ -1114,6 +1103,9 @@ LRESULT CALLBACK mainWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
void SetMouseCapture()
|
||||
{
|
||||
POINT pt = { 0, 0 };
|
||||
RECT re;
|
||||
|
||||
if (mouseToggleReq) {
|
||||
mouseCaptureMode = mouseCaptureNew;
|
||||
mouseToggleReq = FALSE;
|
||||
@ -1122,11 +1114,21 @@ void SetMouseCapture()
|
||||
}
|
||||
ShowCursor(!mouseCaptureMode);
|
||||
ShowCursor(!mouseCaptureMode); // somehow one didn't do the trick (win98)
|
||||
cursorWarped();
|
||||
if (mouseCaptureMode)
|
||||
if (mouseCaptureMode && !win32MouseModeAbsXY) {
|
||||
cursorWarped();
|
||||
}
|
||||
if (mouseCaptureMode) {
|
||||
ClientToScreen(stInfo.simWnd, &pt);
|
||||
re.left = pt.x;
|
||||
re.top = pt.y;
|
||||
re.right = pt.x + stretched_x;
|
||||
re.bottom = pt.y + stretched_y;
|
||||
ClipCursor(&re);
|
||||
SetStatusText(0, szMouseDisable, TRUE);
|
||||
else
|
||||
} else {
|
||||
ClipCursor(NULL);
|
||||
SetStatusText(0, szMouseEnable, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CALLBACK simWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
|
||||
@ -1146,10 +1148,6 @@ LRESULT CALLBACK simWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
|
||||
if (mouseToggleReq && (GetActiveWindow() == stInfo.mainWnd)) {
|
||||
SetMouseCapture();
|
||||
}
|
||||
// If mouse escaped, bring it back
|
||||
if (mouseCaptureMode && !win32MouseModeAbsXY) {
|
||||
cursorWarped();
|
||||
}
|
||||
return 0;
|
||||
|
||||
case WM_PAINT:
|
||||
@ -1177,7 +1175,24 @@ LRESULT CALLBACK simWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
|
||||
LeaveCriticalSection(&stInfo.drawCS);
|
||||
return 0;
|
||||
|
||||
case WM_SIZE:
|
||||
if (mouseCaptureMode) {
|
||||
POINT pt = { 0, 0 };
|
||||
RECT re;
|
||||
ClientToScreen(stInfo.simWnd, &pt);
|
||||
re.left = pt.x;
|
||||
re.top = pt.y;
|
||||
re.right = pt.x + stretched_x;
|
||||
re.bottom = pt.y + stretched_y;
|
||||
ClipCursor(&re);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
if ((LOWORD(lParam) == ms_savedx) && (HIWORD(lParam) == ms_savedy)) {
|
||||
// Ignore mouse event generated by SetCursorPos().
|
||||
return 0;
|
||||
}
|
||||
if (!mouseModeChange) {
|
||||
processMouseXY(LOWORD(lParam), HIWORD(lParam), 0, (int) wParam, 0);
|
||||
}
|
||||
@ -1426,8 +1441,7 @@ void enq_key_event(Bit32u key, Bit32u press_release)
|
||||
void enq_mouse_event(void)
|
||||
{
|
||||
EnterCriticalSection(&stInfo.mouseCS);
|
||||
if (ms_xdelta || ms_ydelta || ms_zdelta)
|
||||
{
|
||||
if (ms_xdelta || ms_ydelta || ms_zdelta) {
|
||||
if (((tail+1) % SCANCODE_BUFSIZE) == head) {
|
||||
LeaveCriticalSection(&stInfo.mouseCS);
|
||||
BX_ERROR(("enq_scancode: buffer full"));
|
||||
@ -1442,9 +1456,9 @@ void enq_mouse_event(void)
|
||||
current.mouse_x = ms_xdelta;
|
||||
current.mouse_y = ms_ydelta;
|
||||
}
|
||||
current.mouse_z=ms_zdelta;
|
||||
current.mouse_button_state=mouse_button_state;
|
||||
resetDelta();
|
||||
current.mouse_z = ms_zdelta;
|
||||
current.mouse_button_state = mouse_button_state;
|
||||
ms_ydelta = ms_xdelta = ms_zdelta = 0;
|
||||
tail = (tail + 1) % SCANCODE_BUFSIZE;
|
||||
}
|
||||
LeaveCriticalSection(&stInfo.mouseCS);
|
||||
|
Loading…
Reference in New Issue
Block a user