diff --git a/src/core/windows/SDL_windows.h b/src/core/windows/SDL_windows.h index ab21627d6..0c0486673 100755 --- a/src/core/windows/SDL_windows.h +++ b/src/core/windows/SDL_windows.h @@ -30,7 +30,7 @@ #define UNICODE 1 #endif #undef _WIN32_WINNT -#define _WIN32_WINNT 0x500 /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices() */ +#define _WIN32_WINNT 0x501 /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices(), 0x501 for raw input */ #include diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index d844fba20..fa1c33474 100755 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -173,6 +173,24 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) if (SDL_GetKeyboardFocus() != data->window) { SDL_SetKeyboardFocus(data->window); } + + if(SDL_GetMouse()->relative_mode) { + LONG cx, cy; + RECT rect; + GetWindowRect(hwnd, &rect); + + cx = (rect.left + rect.right) / 2; + cy = (rect.top + rect.bottom) / 2; + + /* Make an absurdly small clip rect */ + rect.left = cx-1; + rect.right = cx+1; + rect.top = cy-1; + rect.bottom = cy+1; + + ClipCursor(&rect); + } + /* * FIXME: Update keyboard state */ @@ -191,6 +209,8 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) break; case WM_MOUSEMOVE: + if(SDL_GetMouse()->relative_mode) + break; #ifdef _WIN32_WCE /* transform coords for VGA, WVGA... */ { @@ -208,6 +228,25 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) SDL_SendMouseMotion(data->window, 0, LOWORD(lParam), HIWORD(lParam)); break; + case WM_INPUT: + { + HRAWINPUT hRawInput = (HRAWINPUT)lParam; + RAWINPUT inp; + UINT size = sizeof(inp); + GetRawInputData(hRawInput, RID_INPUT, &inp, &size, sizeof(RAWINPUTHEADER)); + + /* Mouse data */ + if(inp.header.dwType == RIM_TYPEMOUSE) + { + RAWMOUSE* mouse = &inp.data.mouse; + + if((mouse->usFlags & 0x01) == MOUSE_MOVE_RELATIVE) + SDL_SendMouseMotion(data->window, 1, (int)mouse->lLastX, (int)mouse->lLastY); + + } + break; + } + case WM_LBUTTONDOWN: SDL_SendMouseButton(data->window, SDL_PRESSED, SDL_BUTTON_LEFT); break; diff --git a/src/video/windows/SDL_windowsmouse.c b/src/video/windows/SDL_windowsmouse.c index 73103c4c7..d0d30b945 100755 --- a/src/video/windows/SDL_windowsmouse.c +++ b/src/video/windows/SDL_windowsmouse.c @@ -140,8 +140,48 @@ WIN_WarpMouse(SDL_Window * window, int x, int y) static int WIN_SetRelativeMouseMode(SDL_bool enabled) { - SDL_Unsupported(); - return -1; + RAWINPUTDEVICE rawMouse = { 0x01, 0x02, 0, NULL }; /* Mouse: UsagePage = 1, Usage = 2 */ + HWND hWnd; + hWnd = GetActiveWindow(); + + rawMouse.hwndTarget = hWnd; + if(!enabled) { + rawMouse.dwFlags |= RIDEV_REMOVE; + rawMouse.hwndTarget = NULL; + } + + + /* (Un)register raw input for mice */ + if(RegisterRawInputDevices(&rawMouse, 1, sizeof(RAWINPUTDEVICE)) == FALSE) { + + /* Only return an error when registering. If we unregister and fail, then + it's probably that we unregistered twice. That's OK. */ + if(enabled) { + SDL_Unsupported(); + return -1; + } + } + + if(enabled) { + LONG cx, cy; + RECT rect; + GetWindowRect(hWnd, &rect); + + cx = (rect.left + rect.right) / 2; + cy = (rect.top + rect.bottom) / 2; + + /* Make an absurdly small clip rect */ + rect.left = cx-1; + rect.right = cx+1; + rect.top = cy-1; + rect.bottom = cy+1; + + ClipCursor(&rect); + } + else + ClipCursor(NULL); + + return 0; } void