2
0
Эх сурвалжийг харах

allow fullscreen borderless on windows

Nicolas Cannasse 8 жил өмнө
parent
commit
97d0f120ab

+ 59 - 3
libs/sdl/sdl.c

@@ -4,6 +4,7 @@
 
 #ifdef _WIN32
 #	include <SDL.h>
+#	include <SDL_syswm.h>
 #else
 #	include <SDL2/SDL.h>
 #endif
@@ -12,6 +13,14 @@
 #	error "SDL2 SDK not found in hl/include/sdl/"
 #endif
 
+typedef struct {
+	int x;
+	int y;
+	int w;
+	int h;
+	int style;
+} wsave_pos;
+
 typedef enum {
 	Quit,
 	MouseMove,
@@ -278,8 +287,55 @@ HL_PRIM SDL_GLContext HL_NAME(win_get_glcontext)(SDL_Window *win) {
 	return SDL_GL_CreateContext(win);
 }
 
-HL_PRIM bool HL_NAME(win_set_fullscreen)(SDL_Window *win, bool b) {
-	return SDL_SetWindowFullscreen(win, b ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0) == 0;
+HL_PRIM bool HL_NAME(win_set_fullscreen)(SDL_Window *win, int mode) {
+#	ifdef HL_WIN
+	wsave_pos *save = SDL_GetWindowData(win,"save");
+	SDL_SysWMinfo info;
+	HWND wnd;
+	SDL_VERSION(&info.version);
+	SDL_GetWindowWMInfo(win,&info);
+	wnd = info.info.win.window;
+	if( save && mode != 2 ) {
+		// exit borderless
+		SetWindowLong(wnd,GWL_STYLE,save->style);
+		SetWindowPos(wnd,NULL,save->x,save->y,save->w,save->h,0);
+		free(save);
+		SDL_SetWindowData(win,"save",NULL);
+		save = NULL;
+	}
+#	endif
+	switch( mode ) {
+	case 0: // WINDOWED
+		return SDL_SetWindowFullscreen(win, 0) == 0;
+	case 1: // FULLSCREEN
+		return SDL_SetWindowFullscreen(win, SDL_WINDOW_FULLSCREEN_DESKTOP) == 0;
+	case 2: // BORDERLESS
+#		ifdef _WIN32
+		{
+			HMONITOR hmon = MonitorFromWindow(wnd,MONITOR_DEFAULTTONEAREST);
+			MONITORINFO mi = { sizeof(mi) };
+			RECT r;
+			if( !GetMonitorInfo(hmon, &mi) )
+				return false;
+			GetWindowRect(wnd,&r);
+			save = (wsave_pos*)malloc(sizeof(wsave_pos));
+			save->x = r.left;
+			save->y = r.top;
+			save->w = r.right - r.left;
+			save->h = r.bottom - r.top;
+			save->style = GetWindowLong(wnd,GWL_STYLE);
+			SDL_SetWindowData(win,"save",save);
+			SetWindowLong(wnd,GWL_STYLE, WS_POPUP | WS_VISIBLE);
+			SetWindowPos(wnd,NULL,mi.rcMonitor.left,mi.rcMonitor.top,mi.rcMonitor.right - mi.rcMonitor.left,mi.rcMonitor.bottom - mi.rcMonitor.top + 1 /* prevent opengl driver to use exclusive mode !*/,0);
+			return true;
+		}
+#	else
+		break;
+#	endif
+	case 3:
+		return SDL_SetWindowFullscreen(win, SDL_WINDOW_FULLSCREEN) == 0;
+	}
+	return false;
 }
 
 HL_PRIM void HL_NAME(win_set_size)(SDL_Window *win, int width, int height) {
@@ -324,7 +380,7 @@ HL_PRIM void HL_NAME(win_destroy)(SDL_Window *win, SDL_GLContext gl) {
 #define TGL _ABSTRACT(sdl_gl)
 DEFINE_PRIM(TWIN, win_create, _BYTES _I32 _I32);
 DEFINE_PRIM(TGL, win_get_glcontext, TWIN);
-DEFINE_PRIM(_BOOL, win_set_fullscreen, TWIN _BOOL);
+DEFINE_PRIM(_BOOL, win_set_fullscreen, TWIN _I32);
 DEFINE_PRIM(_VOID, win_resize, TWIN _I32);
 DEFINE_PRIM(_VOID, win_set_size, TWIN _I32 _I32);
 DEFINE_PRIM(_VOID, win_get_size, TWIN _REF(_I32) _REF(_I32));

+ 8 - 8
libs/sdl/sdl/Sdl.hx

@@ -71,13 +71,13 @@ class Sdl {
 		if( dismissErrors )
 			return;
 
-		var wasFS = null;
+		var wasFS = [];
 		for( w in @:privateAccess Window.windows ) {
-			if( w.fullScreen ) {
-				// SDL full screen does not play well with error dialog
-				w.fullScreen = false;
-				wasFS = w;
-				break;
+			switch( w.displayMode ) {
+			case Windowed, Borderless:
+			default:
+				wasFS.push({ w : w, mode : w.displayMode });
+				w.displayMode = Windowed;
 			}
 		}
 
@@ -103,8 +103,8 @@ class Sdl {
 			tick();
 		f.destroy();
 
-		if( wasFS != null )
-			wasFS.fullScreen = true;
+		for( w in wasFS )
+			w.w.displayMode = w.mode;
 	}
 
 	public static function quit() {

+ 18 - 8
libs/sdl/sdl/Window.hx

@@ -3,6 +3,16 @@ package sdl;
 private typedef WinPtr = hl.Abstract<"sdl_window">;
 private typedef GLContext = hl.Abstract<"sdl_gl">;
 
+@:enum abstract DisplayMode(Int) {
+	var Windowed = 0;
+	var Fullscreen = 1;
+	/**
+		Fullscreen not exclusive.
+	**/
+	var Borderless = 2;
+	var FullscreenResize = 3;
+}
+
 @:hlNative("sdl")
 class Window {
 
@@ -14,7 +24,7 @@ class Window {
 	public var vsync(default, set) : Bool;
 	public var width(get, never) : Int;
 	public var height(get, never) : Int;
-	public var fullScreen(default, set) : Bool;
+	public var displayMode(default, set) : DisplayMode;
 
 	public function new( title : String, width : Int, height : Int ) {
 		win = winCreate(@:privateAccess title.toUtf8(), width, height);
@@ -26,12 +36,12 @@ class Window {
 		vsync = true;
 	}
 
-	function set_fullScreen(b) {
-		if( b == fullScreen )
-			return b;
-		if( winSetFullscreen(win, b) )
-			fullScreen = b;
-		return fullScreen;
+	function set_displayMode(mode) {
+		if( mode == displayMode )
+			return mode;
+		if( winSetFullscreen(win, cast mode) )
+			displayMode = mode;
+		return displayMode;
 	}
 
 	public function resize( width : Int, height : Int ) {
@@ -103,7 +113,7 @@ class Window {
 	static function winSwapWindow( win : WinPtr ) {
 	}
 
-	static function winSetFullscreen( win : WinPtr, b : Bool ) {
+	static function winSetFullscreen( win : WinPtr, mode : DisplayMode ) {
 		return false;
 	}