Improvements from Alfred:
authorSam Lantinga <slouken@libsdl.org>
Mon, 31 Dec 2012 09:30:15 -0800
changeset 6782 582d35419e8a
parent 6781 17a9b53a5ac3
child 6783 001f59dc43be
Improvements from Alfred: - Added new SDL_HINT_ALLOW_TOPMOST hint, when set to "0" then never set the topmost bit on a window. Useful when debugging fullscreen issues. - fixed crash in windows joystick scanning if we failed to load the xinput dll - added support for SDL_WINDOW_FULLSCREEN_DESKTOP under windows - synthesize relative mouse movements if directinput fails to send relative moves, happens under virtual box.
include/SDL_hints.h
src/joystick/windows/SDL_dxjoystick.c
src/render/direct3d/SDL_render_d3d.c
src/video/windows/SDL_windowsevents.c
src/video/windows/SDL_windowswindow.c
--- a/include/SDL_hints.h	Sun Dec 30 19:05:50 2012 -0800
+++ b/include/SDL_hints.h	Mon Dec 31 09:30:15 2012 -0800
@@ -205,6 +205,18 @@
 
 
 /**
+ *  \brief If set to 0 then never set the top most bit on a SDL Window, even if the video mode expects it.
+ *		This is a debugging aid for developers and not expected to be used by end users. The default is "1"
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - don't allow topmost
+ *    "1"       - allow topmost
+ */
+#define SDL_HINT_ALLOW_TOPMOST "SDL_ALLOW_TOPMOST"
+
+
+
+/**
  *  \brief  An enumeration of hint priorities
  */
 typedef enum
--- a/src/joystick/windows/SDL_dxjoystick.c	Sun Dec 30 19:05:50 2012 -0800
+++ b/src/joystick/windows/SDL_dxjoystick.c	Mon Dec 31 09:30:15 2012 -0800
@@ -569,28 +569,30 @@
 			}
 		}
 
-		// scan for any change in XInput devices
-		for ( userId = 0; userId < 4; userId++ )
+		if ( XINPUTGETCAPABILITIES )
 		{
-			XINPUT_CAPABILITIES	capabilities;
-			DWORD result;
+			// scan for any change in XInput devices
+			for ( userId = 0; userId < 4; userId++ )
+			{
+				XINPUT_CAPABILITIES	capabilities;
+				DWORD result;
 
-			if ( bOpenedXInputDevices[userId] == SDL_TRUE )
-				nCurrentOpenedXInputDevices++;
+				if ( bOpenedXInputDevices[userId] == SDL_TRUE )
+					nCurrentOpenedXInputDevices++;
 
-			result = XINPUTGETCAPABILITIES( userId, XINPUT_FLAG_GAMEPAD, &capabilities );
-			if ( result == ERROR_SUCCESS )
-			{
-				bOpenedXInputDevices[userId] = SDL_TRUE;
-				nNewOpenedXInputDevices++;
-			}
-			else
-			{
-				bOpenedXInputDevices[userId] = SDL_FALSE;
+				result = XINPUTGETCAPABILITIES( userId, XINPUT_FLAG_GAMEPAD, &capabilities );
+				if ( result == ERROR_SUCCESS )
+				{
+					bOpenedXInputDevices[userId] = SDL_TRUE;
+					nNewOpenedXInputDevices++;
+				}
+				else
+				{
+					bOpenedXInputDevices[userId] = SDL_FALSE;
+				}
 			}
 		}
 
-
 		if ( s_pKnownJoystickGUIDs && ( s_bWindowsDeviceChanged || nNewOpenedXInputDevices != nCurrentOpenedXInputDevices ) )
 		{
 			SDL_Delay( 300 ); // wait for direct input to find out about this device
--- a/src/render/direct3d/SDL_render_d3d.c	Sun Dec 30 19:05:50 2012 -0800
+++ b/src/render/direct3d/SDL_render_d3d.c	Mon Dec 31 09:30:15 2012 -0800
@@ -538,9 +538,14 @@
     pparams.SwapEffect = D3DSWAPEFFECT_DISCARD;
 
     if (window_flags & SDL_WINDOW_FULLSCREEN) {
+		if ( ( window_flags & SDL_WINDOW_FULLSCREEN_DESKTOP ) == SDL_WINDOW_FULLSCREEN_DESKTOP )  {
+			pparams.Windowed = TRUE;
+			pparams.FullScreen_RefreshRateInHz = 0;
+		} else {
         pparams.Windowed = FALSE;
         pparams.FullScreen_RefreshRateInHz =
             fullscreen_mode.refresh_rate;
+		}
     } else {
         pparams.Windowed = TRUE;
         pparams.FullScreen_RefreshRateInHz = 0;
--- a/src/video/windows/SDL_windowsevents.c	Sun Dec 30 19:05:50 2012 -0800
+++ b/src/video/windows/SDL_windowsevents.c	Mon Dec 31 09:30:15 2012 -0800
@@ -221,6 +221,10 @@
 		HRAWINPUT hRawInput = (HRAWINPUT)lParam;
 		RAWINPUT inp;
 		UINT size = sizeof(inp);
+
+		if(!SDL_GetMouse()->relative_mode)
+			break;
+
 		GetRawInputData(hRawInput, RID_INPUT, &inp, &size, sizeof(RAWINPUTHEADER));
 
 		/* Mouse data */
@@ -229,8 +233,24 @@
 			RAWMOUSE* mouse = &inp.data.mouse;
 
 			if((mouse->usFlags & 0x01) == MOUSE_MOVE_RELATIVE)
+			{
 				SDL_SendMouseMotion(data->window, 1, (int)mouse->lLastX, (int)mouse->lLastY);
+			}
+			else
+			{
+				// synthesize relative moves from the abs position
+				static SDL_Point initialMousePoint;
+				if ( initialMousePoint.x == 0 && initialMousePoint.y == 0 )
+				{
+					initialMousePoint.x = mouse->lLastX;
+					initialMousePoint.y = mouse->lLastY;
+				}
 
+				SDL_SendMouseMotion(data->window, 1, (int)(mouse->lLastX-initialMousePoint.x), (int)(mouse->lLastY-initialMousePoint.y) );
+
+				initialMousePoint.x = mouse->lLastX;
+				initialMousePoint.y = mouse->lLastY;
+			}
 		}
 		break;
 	}
--- a/src/video/windows/SDL_windowswindow.c	Sun Dec 30 19:05:50 2012 -0800
+++ b/src/video/windows/SDL_windowswindow.c	Mon Dec 31 09:30:15 2012 -0800
@@ -28,6 +28,7 @@
 
 #include "SDL_windowsvideo.h"
 #include "SDL_windowswindow.h"
+#include "SDL_hints.h"
 
 /* Dropfile support */
 #include <shellapi.h>
@@ -73,6 +74,22 @@
     return style;
 }
 
+static SDL_bool
+ShouldAllowTopMost()
+{
+    const char *hint;
+
+    /* If the user has specified a software renderer we can't use a
+       texture framebuffer, or renderer creation will go recursive.
+     */
+    hint = SDL_GetHint(SDL_HINT_ALLOW_TOPMOST);
+    if (hint && hint[0] == '0' ) {
+        return SDL_FALSE;
+    }
+
+	return SDL_TRUE;
+}
+
 static int
 SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, SDL_bool created)
 {
@@ -354,8 +371,8 @@
     int w, h;
 
     /* Figure out what the window area will be */
-    if (window->flags & SDL_WINDOW_FULLSCREEN) {
-        top = HWND_TOPMOST;
+    if ( ShouldAllowTopMost() && (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS)) == (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS )) {
+		top = HWND_TOPMOST;
     } else {
         top = HWND_NOTOPMOST;
     }
@@ -406,11 +423,11 @@
     HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
     HWND top;
 
-    if (window->flags & SDL_WINDOW_FULLSCREEN) {
-        top = HWND_TOPMOST;
-    } else {
-        top = HWND_NOTOPMOST;
-    }
+	if ( ShouldAllowTopMost() && (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS)) == (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS )) {
+		top = HWND_TOPMOST;
+	} else {
+		top = HWND_NOTOPMOST;
+	}
     SetWindowPos(hwnd, top, 0, 0, 0, 0, (SWP_NOMOVE | SWP_NOSIZE));
 }
 
@@ -467,11 +484,12 @@
     int x, y;
     int w, h;
 
-    if (fullscreen) {
-        top = HWND_TOPMOST;
-    } else {
-        top = HWND_NOTOPMOST;
-    }
+	if ( ShouldAllowTopMost() && (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS)) == (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS )) {
+		top = HWND_TOPMOST;
+	} else {
+		top = HWND_NOTOPMOST;
+	}
+
     style = GetWindowLong(hwnd, GWL_STYLE);
     style &= ~STYLE_MASK;
     style |= GetWindowStyle(window);
@@ -551,6 +569,23 @@
     } else {
         ClipCursor(NULL);
     }
+
+	if ( window->flags & SDL_WINDOW_FULLSCREEN )
+	{
+		HWND top;
+		SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+		HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
+		UINT flags = SWP_NOMOVE | SWP_NOSIZE;
+
+		if ( ShouldAllowTopMost() && (window->flags & SDL_WINDOW_INPUT_FOCUS ) ) {
+			top = HWND_TOPMOST;
+		} else {
+			top = HWND_NOTOPMOST;
+			flags |= SWP_NOZORDER;
+		}
+		
+		SetWindowPos(hwnd, top, 0, 0, 0, 0, flags);
+	}
 }
 
 void