From 60bee81ce803959461493d107ad5a0e568c958c8 Mon Sep 17 00:00:00 2001 From: tma Date: Sun, 31 Aug 2008 10:41:30 +0000 Subject: * Update SDL patch (again) git-svn-id: svn://svn.icculus.org/quake3/trunk@1467 edf5b092-35ff-0310-97b2-ce42778d08ea --- README | 2 +- misc/sdl-win32-fixes.diff | 583 ++++++++++++++++++++++++++++++++++++++++ misc/sdl-win32-mouse-fixes.diff | 571 --------------------------------------- 3 files changed, 584 insertions(+), 572 deletions(-) create mode 100644 misc/sdl-win32-fixes.diff delete mode 100644 misc/sdl-win32-mouse-fixes.diff diff --git a/README b/README index c80faca..fa03714 100644 --- a/README +++ b/README @@ -433,7 +433,7 @@ Mouse Input On Windows * Low quality mouse input data when using the windib driver due to use of WM_MOUSEMOVE events. Use GetCursorPos API call instead. - The patch can be found in misc/sdl-win32-mouse-fixes.diff. + The patch can be found in misc/sdl-win32-fixes.diff. PNG support ioquake3 supports the use of PNG (Portable Network Graphic) images as 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, ¢er); +- 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, ¢er); ++ ++ 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(¤t_x, ¤t_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, ¢er); ++ 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 + #include + ++#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" diff --git a/misc/sdl-win32-mouse-fixes.diff b/misc/sdl-win32-mouse-fixes.diff deleted file mode 100644 index faec492..0000000 --- a/misc/sdl-win32-mouse-fixes.diff +++ /dev/null @@ -1,571 +0,0 @@ -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, ¢er); -- 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, ¢er); -+ -+ 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(¤t_x, ¤t_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, ¢er); -+ 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); - } - } - -@@ -840,7 +912,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 - #include - -+#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" -- cgit v1.2.3