From ac608856747482553cc4f860079fa6f45ef7dde9 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 27 Sep 2009 05:18:43 +0000 Subject: [PATCH] Fixed bug #713 Don't clamp the mouse coordinates to the video surface size, instead clamp them to the last known window size. This allows users to get the correct mouse coordinates even if they don't call SDL_SetVideoMode() in response to an SDL_VIDEORESIZE event (used as a hack to retain the OpenGL context on Windows and Linux after a window resize) --- src/events/SDL_events_c.h | 3 +++ src/events/SDL_mouse.c | 33 +++++++++++++++++------------ src/events/SDL_resize.c | 1 + src/video/SDL_video.c | 1 + src/video/wincommon/SDL_sysevents.c | 1 - 5 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/events/SDL_events_c.h b/src/events/SDL_events_c.h index 8fe8950a2..421bb75dd 100644 --- a/src/events/SDL_events_c.h +++ b/src/events/SDL_events_c.h @@ -64,6 +64,9 @@ extern int SDL_PrivateExpose(void); extern int SDL_PrivateQuit(void); extern int SDL_PrivateSysWMEvent(SDL_SysWMmsg *message); +/* Used to clamp the mouse coordinates separately from the video surface */ +extern void SDL_SetMouseRange(int maxX, int maxY); + /* Used by the activity event handler to remove mouse focus */ extern void SDL_ResetMouse(void); diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c index c9839e3ef..d68e22b3f 100644 --- a/src/events/SDL_mouse.c +++ b/src/events/SDL_mouse.c @@ -34,6 +34,8 @@ static Sint16 SDL_MouseX = 0; static Sint16 SDL_MouseY = 0; static Sint16 SDL_DeltaX = 0; static Sint16 SDL_DeltaY = 0; +static Sint16 SDL_MouseMaxX = 0; +static Sint16 SDL_MouseMaxY = 0; static Uint8 SDL_ButtonState = 0; @@ -45,6 +47,8 @@ int SDL_MouseInit(void) SDL_MouseY = 0; SDL_DeltaX = 0; SDL_DeltaY = 0; + SDL_MouseMaxX = 0; + SDL_MouseMaxY = 0; SDL_ButtonState = 0; /* That's it! */ @@ -92,13 +96,19 @@ static void ClipOffset(Sint16 *x, Sint16 *y) /* This clips absolute mouse coordinates when the apparent display surface is smaller than the real display surface. */ - if ( SDL_VideoSurface->offset ) { + if ( SDL_VideoSurface && SDL_VideoSurface->offset ) { *y -= SDL_VideoSurface->offset/SDL_VideoSurface->pitch; *x -= (SDL_VideoSurface->offset%SDL_VideoSurface->pitch)/ SDL_VideoSurface->format->BytesPerPixel; } } +void SDL_SetMouseRange(int maxX, int maxY) +{ + SDL_MouseMaxX = (Sint16)maxX; + SDL_MouseMaxY = (Sint16)maxY; +} + /* These are global for SDL_eventloop.c */ int SDL_PrivateMouseMotion(Uint8 buttonstate, int relative, Sint16 x, Sint16 y) { @@ -107,11 +117,6 @@ int SDL_PrivateMouseMotion(Uint8 buttonstate, int relative, Sint16 x, Sint16 y) Sint16 Xrel; Sint16 Yrel; - /* Don't handle mouse motion if there's no cursor surface */ - if ( SDL_VideoSurface == NULL ) { - return(0); - } - /* Default buttonstate is the current one */ if ( ! buttonstate ) { buttonstate = SDL_ButtonState; @@ -132,16 +137,16 @@ int SDL_PrivateMouseMotion(Uint8 buttonstate, int relative, Sint16 x, Sint16 y) if ( x < 0 ) X = 0; else - if ( x >= SDL_VideoSurface->w ) - X = SDL_VideoSurface->w-1; + if ( x >= SDL_MouseMaxX ) + X = SDL_MouseMaxX-1; else X = (Uint16)x; if ( y < 0 ) Y = 0; else - if ( y >= SDL_VideoSurface->h ) - Y = SDL_VideoSurface->h-1; + if ( y >= SDL_MouseMaxY ) + Y = SDL_MouseMaxY-1; else Y = (Uint16)y; @@ -206,14 +211,14 @@ int SDL_PrivateMouseButton(Uint8 state, Uint8 button, Sint16 x, Sint16 y) if ( x < 0 ) x = 0; else - if ( x >= SDL_VideoSurface->w ) - x = SDL_VideoSurface->w-1; + if ( x >= SDL_MouseMaxX ) + x = SDL_MouseMaxX-1; if ( y < 0 ) y = 0; else - if ( y >= SDL_VideoSurface->h ) - y = SDL_VideoSurface->h-1; + if ( y >= SDL_MouseMaxY ) + y = SDL_MouseMaxY-1; } else { move_mouse = 0; } diff --git a/src/events/SDL_resize.c b/src/events/SDL_resize.c index 71de55eb3..2c646d33c 100644 --- a/src/events/SDL_resize.c +++ b/src/events/SDL_resize.c @@ -54,6 +54,7 @@ int SDL_PrivateResize(int w, int h) ((w == SDL_VideoSurface->w) && (h == SDL_VideoSurface->h)) ) { return(0); } + SDL_SetMouseRange(w, h); /* Pull out all old resize events */ SDL_PeepEvents(events, sizeof(events)/sizeof(events[0]), diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 4d250b39c..dfbf9f0ea 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -639,6 +639,7 @@ SDL_Surface * SDL_SetVideoMode (int width, int height, int bpp, Uint32 flags) /* Reset the keyboard here so event callbacks can run */ SDL_ResetKeyboard(); SDL_ResetMouse(); + SDL_SetMouseRange(width, height); SDL_cursorstate &= ~CURSOR_USINGSW; /* Clean up any previous video mode */ diff --git a/src/video/wincommon/SDL_sysevents.c b/src/video/wincommon/SDL_sysevents.c index 5e090fc40..22e75f9a3 100644 --- a/src/video/wincommon/SDL_sysevents.c +++ b/src/video/wincommon/SDL_sysevents.c @@ -420,7 +420,6 @@ LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) /* Mouse is handled by DirectInput when fullscreen */ if ( SDL_VideoSurface && ! DINPUT() ) { WORD xbuttonval = 0; - Sint16 x, y; Uint8 button, state; /* DJM: