aboutsummaryrefslogtreecommitdiffstats
path: root/misc/sdl-win32-fixes.diff
diff options
context:
space:
mode:
Diffstat (limited to 'misc/sdl-win32-fixes.diff')
-rw-r--r--misc/sdl-win32-fixes.diff583
1 files changed, 583 insertions, 0 deletions
diff --git a/misc/sdl-win32-fixes.diff b/misc/sdl-win32-fixes.diff
new file mode 100644
index 0000000..2a4ff63
--- /dev/null
+++ b/misc/sdl-win32-fixes.diff
@@ -0,0 +1,583 @@
+Index: src/video/wincommon/SDL_lowvideo.h
+===================================================================
+--- src/video/wincommon/SDL_lowvideo.h (revision 4067)
++++ src/video/wincommon/SDL_lowvideo.h (working copy)
+@@ -51,10 +51,13 @@
+ /* Hidden "this" pointer for the video functions */
+ #define _THIS SDL_VideoDevice *this
+
++#define FULLSCREEN() \
++ ((SDL_VideoSurface->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN)
++
+ #define WINDIB_FULLSCREEN() \
+ ( \
+ SDL_VideoSurface && \
+- ((SDL_VideoSurface->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) && \
++ FULLSCREEN() && \
+ (((SDL_VideoSurface->flags & SDL_OPENGL ) == SDL_OPENGL ) || \
+ ((SDL_strcmp(this->name, "windib") == 0) || \
+ (SDL_strcmp(this->name, "gapi") == 0))) \
+@@ -62,13 +65,19 @@
+ #define DDRAW_FULLSCREEN() \
+ ( \
+ SDL_VideoSurface && \
+- ((SDL_VideoSurface->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) && \
++ FULLSCREEN() && \
+ ((SDL_VideoSurface->flags & SDL_OPENGL ) != SDL_OPENGL ) && \
+ (SDL_strcmp(this->name, "directx") == 0) \
+ )
+
+-#define DINPUT_FULLSCREEN() DDRAW_FULLSCREEN()
++#define DINPUT_FULLSCREEN() \
++( \
++ FULLSCREEN() && \
++ (strcmp(this->name, "directx") == 0) \
++)
+
++#define DINPUT() (strcmp(this->name, "directx") == 0)
++
+ /* The main window -- and a function to set it for the audio */
+ #ifdef _WIN32_WCE
+ extern LPWSTR SDL_Appname;
+Index: src/video/wincommon/SDL_sysevents.c
+===================================================================
+--- src/video/wincommon/SDL_sysevents.c (revision 4067)
++++ src/video/wincommon/SDL_sysevents.c (working copy)
+@@ -335,7 +335,6 @@
+ {
+ SDL_VideoDevice *this = current_video;
+ static int mouse_pressed = 0;
+- static int in_window = 0;
+ #ifdef WMMSG_DEBUG
+ fprintf(stderr, "Received windows message: ");
+ if ( msg > MAX_WMMSG ) {
+@@ -411,62 +410,41 @@
+ break;
+
+ case WM_MOUSEMOVE: {
+-
+- /* Mouse is handled by DirectInput when fullscreen */
+- if ( SDL_VideoSurface && ! DINPUT_FULLSCREEN() ) {
+- Sint16 x, y;
+
+- /* mouse has entered the window */
+- if ( ! in_window ) {
+ #ifdef WM_MOUSELEAVE
++ /* No need to handle SDL_APPMOUSEFOCUS when fullscreen */
++ if ( SDL_VideoSurface && !FULLSCREEN() ) {
++ /* mouse has entered the window */
++
++ if ( !(SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) {
+ TRACKMOUSEEVENT tme;
+
+ tme.cbSize = sizeof(tme);
+ tme.dwFlags = TME_LEAVE;
+ tme.hwndTrack = SDL_Window;
+ _TrackMouseEvent(&tme);
++ }
++ }
+ #endif /* WM_MOUSELEAVE */
+- in_window = TRUE;
+
+- posted = SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
+- }
++ /* Mouse motion is handled in DIB_PumpEvents or
++ * DX5_PumpEvents, depending on the video driver
++ * in use */
+
+- /* mouse has moved within the window */
+- x = LOWORD(lParam);
+- y = HIWORD(lParam);
+- if ( mouse_relative ) {
+- POINT center;
+- center.x = (SDL_VideoSurface->w/2);
+- center.y = (SDL_VideoSurface->h/2);
+- x -= (Sint16)center.x;
+- y -= (Sint16)center.y;
+- if ( x || y ) {
+- ClientToScreen(SDL_Window, &center);
+- SetCursorPos(center.x, center.y);
+- posted = SDL_PrivateMouseMotion(0, 1, x, y);
+- }
+- } else {
+-#ifdef _WIN32_WCE
+- if (SDL_VideoSurface)
+- GapiTransform(this->hidden->userOrientation, this->hidden->hiresFix, &x, &y);
+-#endif
+- posted = SDL_PrivateMouseMotion(0, 0, x, y);
+- }
+- }
++ posted = SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
+ }
+ return(0);
+
+ #ifdef WM_MOUSELEAVE
+ case WM_MOUSELEAVE: {
+
+- /* Mouse is handled by DirectInput when fullscreen */
+- if ( SDL_VideoSurface && ! DINPUT_FULLSCREEN() ) {
++ /* No need to handle SDL_APPMOUSEFOCUS when fullscreen */
++ if ( SDL_VideoSurface && !FULLSCREEN() ) {
+ /* mouse has left the window */
+ /* or */
+ /* Elvis has left the building! */
+ posted = SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
+ }
+- in_window = FALSE;
+ }
+ return(0);
+ #endif /* WM_MOUSELEAVE */
+@@ -480,7 +458,7 @@
+ case WM_XBUTTONDOWN:
+ case WM_XBUTTONUP: {
+ /* Mouse is handled by DirectInput when fullscreen */
+- if ( SDL_VideoSurface && ! DINPUT_FULLSCREEN() ) {
++ if ( SDL_VideoSurface && ! DINPUT() ) {
+ WORD xbuttonval = 0;
+ Sint16 x, y;
+ Uint8 button, state;
+@@ -544,20 +522,8 @@
+ mouse_pressed = 0;
+ }
+ }
+- if ( mouse_relative ) {
+- /* RJR: March 28, 2000
+- report internal mouse position if in relative mode */
+- x = 0; y = 0;
+- } else {
+- x = (Sint16)LOWORD(lParam);
+- y = (Sint16)HIWORD(lParam);
+-#ifdef _WIN32_WCE
+- if (SDL_VideoSurface)
+- GapiTransform(this->hidden->userOrientation, this->hidden->hiresFix, &x, &y);
+-#endif
+- }
+ posted = SDL_PrivateMouseButton(
+- state, button, x, y);
++ state, button, 0, 0);
+
+ /*
+ * MSDN says:
+@@ -578,7 +544,7 @@
+
+ #if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
+ case WM_MOUSEWHEEL:
+- if ( SDL_VideoSurface && ! DINPUT_FULLSCREEN() ) {
++ if ( SDL_VideoSurface && ! DINPUT() ) {
+ int move = (short)HIWORD(wParam);
+ if ( move ) {
+ Uint8 button;
+Index: src/video/wincommon/SDL_sysmouse.c
+===================================================================
+--- src/video/wincommon/SDL_sysmouse.c (revision 4067)
++++ src/video/wincommon/SDL_sysmouse.c (working copy)
+@@ -208,15 +208,20 @@
+
+ void WIN_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
+ {
+- if ( DDRAW_FULLSCREEN() ) {
+- SDL_PrivateMouseMotion(0, 0, x, y);
+- } else if ( mouse_relative) {
++ if ( mouse_relative) {
+ /* RJR: March 28, 2000
+ leave physical cursor at center of screen if
+ mouse hidden and grabbed */
+ SDL_PrivateMouseMotion(0, 0, x, y);
+ } else {
+ POINT pt;
++
++ /* With DirectInput the position doesn't follow
++ * the cursor, so it is set manually */
++ if ( DINPUT() ) {
++ SDL_PrivateMouseMotion(0, 0, x, y);
++ }
++
+ pt.x = x;
+ pt.y = y;
+ ClientToScreen(SDL_Window, &pt);
+@@ -227,20 +232,15 @@
+ /* Update the current mouse state and position */
+ void WIN_UpdateMouse(_THIS)
+ {
+- RECT rect;
+ POINT pt;
+
+- if ( ! DDRAW_FULLSCREEN() ) {
+- GetClientRect(SDL_Window, &rect);
+- GetCursorPos(&pt);
+- MapWindowPoints(NULL, SDL_Window, &pt, 1);
+- if (PtInRect(&rect, pt) && (WindowFromPoint(pt) == SDL_Window)){
+- SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
+- SDL_PrivateMouseMotion(0,0, (Sint16)pt.x, (Sint16)pt.y);
+- } else {
+- SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
+- }
+- }
++ /* Always unset SDL_APPMOUSEFOCUS to give the WM_MOUSEMOVE event
++ * handler a chance to install a TRACKMOUSEEVENT */
++ SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
++
++ GetCursorPos(&pt);
++ ScreenToClient(SDL_Window, &pt);
++ SDL_PrivateMouseMotion(0,0, (Sint16)pt.x, (Sint16)pt.y);
+ }
+
+ /* Check to see if we need to enter or leave mouse relative mode */
+Index: src/video/windib/SDL_dibevents.c
+===================================================================
+--- src/video/windib/SDL_dibevents.c (revision 4067)
++++ src/video/windib/SDL_dibevents.c (working copy)
+@@ -262,6 +262,36 @@
+ return(DefWindowProc(hwnd, msg, wParam, lParam));
+ }
+
++static void DIB_GenerateMouseMotionEvent(void)
++{
++ extern int mouse_relative;
++ extern int posted;
++
++ POINT mouse;
++ GetCursorPos( &mouse );
++
++ if ( mouse_relative ) {
++ POINT center;
++ center.x = (SDL_VideoSurface->w/2);
++ center.y = (SDL_VideoSurface->h/2);
++ ClientToScreen(SDL_Window, &center);
++
++ mouse.x -= (Sint16)center.x;
++ mouse.y -= (Sint16)center.y;
++ if ( mouse.x || mouse.y ) {
++ SetCursorPos(center.x, center.y);
++ posted = SDL_PrivateMouseMotion(0, 1, mouse.x, mouse.y);
++ }
++ } else {
++ ScreenToClient(SDL_Window, &mouse);
++#ifdef _WIN32_WCE
++ if (SDL_VideoSurface)
++ GapiTransform(this->hidden->userOrientation, this->hidden->hiresFix, &mouse.x, &mouse.y);
++#endif
++ posted = SDL_PrivateMouseMotion(0, 0, mouse.x, mouse.y);
++ }
++}
++
+ void DIB_PumpEvents(_THIS)
+ {
+ MSG msg;
+@@ -271,6 +301,10 @@
+ DispatchMessage(&msg);
+ }
+ }
++
++ if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) {
++ DIB_GenerateMouseMotionEvent( );
++ }
+ }
+
+ static HKL hLayoutUS = NULL;
+@@ -494,7 +528,7 @@
+ Uint16 wchars[2];
+
+ GetKeyboardState(keystate);
+- if (SDL_ToUnicode((UINT)vkey, scancode, keystate, wchars, sizeof(wchars)/sizeof(wchars[0]), 0) == 1)
++ if (SDL_ToUnicode((UINT)vkey, scancode, keystate, wchars, sizeof(wchars)/sizeof(wchars[0]), 0) > 0)
+ {
+ keysym->unicode = wchars[0];
+ }
+Index: src/video/windx5/SDL_dx5events.c
+===================================================================
+--- src/video/windx5/SDL_dx5events.c (revision 4067)
++++ src/video/windx5/SDL_dx5events.c (working copy)
+@@ -143,7 +143,12 @@
+ (DISCL_FOREGROUND|DISCL_NONEXCLUSIVE),
+ (DISCL_FOREGROUND|DISCL_NONEXCLUSIVE), handle_keyboard },
+ { "mouse",
+- &GUID_SysMouse, &c_dfDIMouse,
++ &GUID_SysMouse,
++#if DIRECTINPUT_VERSION >= 0x700
++ &c_dfDIMouse2,
++#else
++ &c_dfDIMouse,
++#endif
+ (DISCL_FOREGROUND|DISCL_NONEXCLUSIVE),
+ (DISCL_FOREGROUND|DISCL_EXCLUSIVE), handle_mouse },
+ { NULL, NULL, NULL, 0, 0, NULL }
+@@ -285,6 +290,76 @@
+ }
+ }
+ }
++
++static void post_mouse_motion(int relative, Sint16 x, Sint16 y)
++{
++ extern int mouse_relative;
++
++ if ( SDL_GetAppState() & (SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS) ==
++ (SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS) ) {
++ posted = SDL_PrivateMouseMotion(
++ 0, relative, x, y);
++
++ if ( !mouse_relative ) {
++ /* As DirectInput reads raw device coordinates, it has no notion of
++ * cursors or absolute position. We must assume responsibility for
++ * keeping track of this. */
++ int current_x, current_y;
++ POINT cursor;
++ RECT trap;
++ RECT window;
++ int at_edge;
++
++ /* Get the current cursor position */
++ SDL_GetMouseState(&current_x, &current_y);
++ cursor.x = current_x;
++ cursor.y = current_y;
++ ClientToScreen(SDL_Window, &cursor);
++
++ /* Construct a 1 pixel square RECT that is used to confine the cursor
++ * pointer to a specific pixel using ClipCursor. This is used in
++ * preference to SetCursorPos as it avoids the cursor jumping around as
++ * both the OS and SDL attempt to move it simultaneously. */
++ trap.left = cursor.x;
++ trap.top = cursor.y;
++ trap.right = cursor.x + 1;
++ trap.bottom = cursor.y + 1;
++
++ GetClientRect(SDL_Window, &window);
++ window.right -= window.left; window.left = 0;
++ window.bottom -= window.top; window.top = 0;
++
++ /* As we're assuming control over the cursor, we need to know when to
++ * relinquish control of it back to the operating system. This is when
++ * the cursor reaches the edge of the window. */
++ at_edge = (current_x == window.left) ||
++ (current_x == (window.right - 1)) ||
++ (current_y == window.top) ||
++ (current_y == (window.bottom - 1));
++
++ if ( at_edge ) {
++ ClipCursor(NULL);
++ } else {
++ ClipCursor(&trap);
++ }
++ } else {
++ /* When in relative mode, warp the OS's idea of where the cursor is to
++ * the center of the screen. This isn't really necessary as DirectInput
++ * reads from the hardware itself, but in case things go wrong, the
++ * cursor will be left in a sensible place. */
++ POINT center;
++ center.x = (SDL_VideoSurface->w/2);
++ center.y = (SDL_VideoSurface->h/2);
++ ClientToScreen(SDL_Window, &center);
++ SetCursorPos(center.x, center.y);
++ }
++ } else {
++ /* No window or mouse focus, control is lost */
++ mouse_lost = 1;
++ ClipCursor(NULL);
++ }
++}
++
+ static void handle_mouse(const int numevents, DIDEVICEOBJECTDATA *ptrbuf)
+ {
+ int i;
+@@ -298,14 +373,8 @@
+ return;
+ }
+
+- /* If we are in windowed mode, Windows is taking care of the mouse */
+- if ( (SDL_PublicSurface->flags & SDL_OPENGL) ||
+- !(SDL_PublicSurface->flags & SDL_FULLSCREEN) ) {
+- return;
+- }
+-
+ /* If the mouse was lost, regain some sense of mouse state */
+- if ( mouse_lost ) {
++ if ( mouse_lost && (SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) {
+ POINT mouse_pos;
+ Uint8 old_state;
+ Uint8 new_state;
+@@ -313,14 +382,17 @@
+ /* Set ourselves up with the current cursor position */
+ GetCursorPos(&mouse_pos);
+ ScreenToClient(SDL_Window, &mouse_pos);
+- posted = SDL_PrivateMouseMotion(0, 0,
+- (Sint16)mouse_pos.x, (Sint16)mouse_pos.y);
++ post_mouse_motion( 0, (Sint16)mouse_pos.x, (Sint16)mouse_pos.y);
+
+ /* Check for mouse button changes */
+ old_state = SDL_GetMouseState(NULL, NULL);
+ new_state = 0;
+ { /* Get the new DirectInput button state for the mouse */
++#if DIRECTINPUT_VERSION >= 0x700
++ DIMOUSESTATE2 distate;
++#else
+ DIMOUSESTATE distate;
++#endif
+ HRESULT result;
+
+ result=IDirectInputDevice2_GetDeviceState(SDL_DIdev[1],
+@@ -341,14 +413,13 @@
+ for ( i=0; i<8; ++i ) {
+ if ( (old_state&0x01) != (new_state&0x01) ) {
+ button = (Uint8)(i+1);
+- /* Button #2 on two button mice is button 3
+- (the middle button is button 2)
+- */
+- if ( button == 2 ) {
+- button = 3;
+- } else
+- if ( button == 3 ) {
+- button = 2;
++ /* Map DI button numbers to SDL */
++ switch ( button ) {
++ case 2: button = SDL_BUTTON_RIGHT; break;
++ case 3: button = SDL_BUTTON_MIDDLE; break;
++ case 4: button = SDL_BUTTON_X1; break;
++ case 5: button = SDL_BUTTON_X2; break;
++ default: break;
+ }
+ if ( new_state & 0x01 ) {
+ /* Grab mouse so we get mouse-up */
+@@ -387,8 +458,7 @@
+ case DIMOFS_X:
+ if ( timestamp != ptrbuf[i].dwTimeStamp ) {
+ if ( xrel || yrel ) {
+- posted = SDL_PrivateMouseMotion(
+- 0, 1, xrel, yrel);
++ post_mouse_motion(1, xrel, yrel);
+ xrel = 0;
+ yrel = 0;
+ }
+@@ -399,8 +469,7 @@
+ case DIMOFS_Y:
+ if ( timestamp != ptrbuf[i].dwTimeStamp ) {
+ if ( xrel || yrel ) {
+- posted = SDL_PrivateMouseMotion(
+- 0, 1, xrel, yrel);
++ post_mouse_motion(1, xrel, yrel);
+ xrel = 0;
+ yrel = 0;
+ }
+@@ -410,8 +479,7 @@
+ break;
+ case DIMOFS_Z:
+ if ( xrel || yrel ) {
+- posted = SDL_PrivateMouseMotion(
+- 0, 1, xrel, yrel);
++ post_mouse_motion(1, xrel, yrel);
+ xrel = 0;
+ yrel = 0;
+ }
+@@ -429,22 +497,26 @@
+ case DIMOFS_BUTTON1:
+ case DIMOFS_BUTTON2:
+ case DIMOFS_BUTTON3:
++#if DIRECTINPUT_VERSION >= 0x700
++ case DIMOFS_BUTTON4:
++ case DIMOFS_BUTTON5:
++ case DIMOFS_BUTTON6:
++ case DIMOFS_BUTTON7:
++#endif
+ if ( xrel || yrel ) {
+- posted = SDL_PrivateMouseMotion(
+- 0, 1, xrel, yrel);
++ post_mouse_motion(1, xrel, yrel);
+ xrel = 0;
+ yrel = 0;
+ }
+ timestamp = 0;
+ button = (Uint8)(ptrbuf[i].dwOfs-DIMOFS_BUTTON0)+1;
+- /* Button #2 on two button mice is button 3
+- (the middle button is button 2)
+- */
+- if ( button == 2 ) {
+- button = 3;
+- } else
+- if ( button == 3 ) {
+- button = 2;
++ /* Map DI button numbers to SDL */
++ switch ( button ) {
++ case 2: button = SDL_BUTTON_RIGHT; break;
++ case 3: button = SDL_BUTTON_MIDDLE; break;
++ case 4: button = SDL_BUTTON_X1; break;
++ case 5: button = SDL_BUTTON_X2; break;
++ default: break;
+ }
+ if ( ptrbuf[i].dwData & 0x80 ) {
+ /* Grab mouse so we get mouse-up */
+@@ -471,7 +543,7 @@
+ }
+ }
+ if ( xrel || yrel ) {
+- posted = SDL_PrivateMouseMotion( 0, 1, xrel, yrel);
++ post_mouse_motion(1, xrel, yrel);
+ }
+ }
+
+@@ -516,10 +588,7 @@
+
+ /* The keyboard is handled via DirectInput */
+ case WM_SYSKEYUP:
+- case WM_SYSKEYDOWN: {
+- /* Pass syskey to DefWindwoProc (ALT-F4, etc.) */
+- }
+- break;
++ case WM_SYSKEYDOWN:
+ case WM_KEYUP:
+ case WM_KEYDOWN: {
+ /* Ignore windows keyboard messages */;
+@@ -840,7 +909,7 @@
+ keysym->unicode = vkey;
+ #else
+ GetKeyboardState(keystate);
+- if (SDL_ToUnicode(vkey, scancode, keystate, wchars, sizeof(wchars)/sizeof(wchars[0]), 0) == 1)
++ if (SDL_ToUnicode(vkey, scancode, keystate, wchars, sizeof(wchars)/sizeof(wchars[0]), 0) > 0)
+ {
+ keysym->unicode = wchars[0];
+ }
+Index: src/video/windx5/directx.h
+===================================================================
+--- src/video/windx5/directx.h (revision 4067)
++++ src/video/windx5/directx.h (working copy)
+@@ -72,7 +72,7 @@
+ /* We need these defines to mark what version of DirectX API we use */
+ #define DIRECTDRAW_VERSION 0x0700
+ #define DIRECTSOUND_VERSION 0x0500
+-#define DIRECTINPUT_VERSION 0x0500
++#define DIRECTINPUT_VERSION 0x0700
+
+ #ifdef __GNUC__
+ #define NONAMELESSUNION
+@@ -81,4 +81,20 @@
+ #include <dsound.h>
+ #include <dinput.h>
+
++#if DIRECTINPUT_VERSION >= 0x0700 && !defined(DIMOFS_BUTTON4)
++typedef struct _DIMOUSESTATE2 {
++ LONG lX;
++ LONG lY;
++ LONG lZ;
++ BYTE rgbButtons[8];
++} DIMOUSESTATE2, *LPDIMOUSESTATE2;
++
++#define DIMOFS_BUTTON4 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 4)
++#define DIMOFS_BUTTON5 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 5)
++#define DIMOFS_BUTTON6 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 6)
++#define DIMOFS_BUTTON7 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 7)
++
++extern const DIDATAFORMAT c_dfDIMouse2;
++#endif
++
+ #endif /* _directx_h */
+Index: configure.in
+===================================================================
+--- configure.in (revision 4067)
++++ configure.in (working copy)
+@@ -2442,7 +2442,7 @@
+ # Set up the system libraries we need
+ EXTRA_LDFLAGS="$EXTRA_LDFLAGS -luser32 -lgdi32 -lwinmm"
+ if test x$have_directx = xyes; then
+- EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ldxguid"
++ EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ldxguid -ldinput8"
+ fi
+ # The Win32 platform requires special setup
+ SOURCES="$SOURCES $srcdir/src/main/win32/*.rc"