SDL: Added SDL_RenderViewportSet() to tell whether the viewport was previously set to a specific rectangle.

From 1162097135852f41f451e6c4b64cdf951b7ad7f0 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Fri, 9 Feb 2024 16:37:04 -0800
Subject: [PATCH] Added SDL_RenderViewportSet() to tell whether the viewport
 was previously set to a specific rectangle.

Fixes https://github.com/libsdl-org/SDL/issues/9029
---
 include/SDL3/SDL_render.h         | 17 +++++++++++++++++
 src/dynapi/SDL_dynapi.sym         |  1 +
 src/dynapi/SDL_dynapi_overrides.h |  1 +
 src/dynapi/SDL_dynapi_procs.h     |  1 +
 src/render/SDL_render.c           | 11 +++++++++++
 5 files changed, 31 insertions(+)

diff --git a/include/SDL3/SDL_render.h b/include/SDL3/SDL_render.h
index 026f966e253b..97faa034b46a 100644
--- a/include/SDL3/SDL_render.h
+++ b/include/SDL3/SDL_render.h
@@ -1269,6 +1269,7 @@ extern DECLSPEC int SDLCALL SDL_ConvertEventToRenderCoordinates(SDL_Renderer *re
  * \since This function is available since SDL 3.0.0.
  *
  * \sa SDL_GetRenderViewport
+ * \sa SDL_RenderViewportSet
  */
 extern DECLSPEC int SDLCALL SDL_SetRenderViewport(SDL_Renderer *renderer, const SDL_Rect *rect);
 
@@ -1282,10 +1283,26 @@ extern DECLSPEC int SDLCALL SDL_SetRenderViewport(SDL_Renderer *renderer, const
  *
  * \since This function is available since SDL 3.0.0.
  *
+ * \sa SDL_RenderViewportSet
  * \sa SDL_SetRenderViewport
  */
 extern DECLSPEC int SDLCALL SDL_GetRenderViewport(SDL_Renderer *renderer, SDL_Rect *rect);
 
+/**
+ * Return whether an explicit rectangle was set as the viewport.
+ *
+ * This is useful if you're saving and restoring the viewport and want to know whether you should restore a specific rectangle or NULL. Note that the viewport is always reset when changing rendering targets.
+ *
+ * \param renderer the rendering context
+ * \returns SDL_TRUE if the viewport was set to a specific rectangle, or SDL_FALSE if it was set to NULL (the entire target)
+ *
+ * \since This function is available since SDL 3.0.0.
+ *
+ * \sa SDL_GetRenderViewport
+ * \sa SDL_SetRenderViewport
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_RenderViewportSet(SDL_Renderer *renderer);
+
 /**
  * Set the clip rectangle for rendering on the specified target.
  *
diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym
index 5bf8b931563b..b4dca5f46c10 100644
--- a/src/dynapi/SDL_dynapi.sym
+++ b/src/dynapi/SDL_dynapi.sym
@@ -971,6 +971,7 @@ SDL3_0.0.0 {
     SDL_GetRenderColorScale;
     SDL_RenderGeometryRawFloat;
     SDL_SetWindowShape;
+    SDL_RenderViewportSet;
     # extra symbols go here (don't modify this line)
   local: *;
 };
diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
index ac097b09f5ea..341add8cdcd8 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -996,3 +996,4 @@
 #define SDL_GetRenderColorScale SDL_GetRenderColorScale_REAL
 #define SDL_RenderGeometryRawFloat SDL_RenderGeometryRawFloat_REAL
 #define SDL_SetWindowShape SDL_SetWindowShape_REAL
+#define SDL_RenderViewportSet SDL_RenderViewportSet_REAL
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index 81d1c92966d4..a276a7e97438 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -1021,3 +1021,4 @@ SDL_DYNAPI_PROC(int,SDL_SetRenderColorScale,(SDL_Renderer *a, float b),(a,b),ret
 SDL_DYNAPI_PROC(int,SDL_GetRenderColorScale,(SDL_Renderer *a, float *b),(a,b),return)
 SDL_DYNAPI_PROC(int,SDL_RenderGeometryRawFloat,(SDL_Renderer *a, SDL_Texture *b, const float *c, int d, const SDL_FColor *e, int f, const float *g, int h, int i, const void *j, int k, int l),(a,b,c,d,e,f,g,h,i,j,k,l),return)
 SDL_DYNAPI_PROC(int,SDL_SetWindowShape,(SDL_Window *a, SDL_Surface *b),(a,b),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_RenderViewportSet,(SDL_Renderer *a),(a),return)
diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c
index 03464ef46211..d10e1e3c3fef 100644
--- a/src/render/SDL_render.c
+++ b/src/render/SDL_render.c
@@ -2732,6 +2732,17 @@ int SDL_GetRenderViewport(SDL_Renderer *renderer, SDL_Rect *rect)
     return 0;
 }
 
+SDL_bool SDL_RenderViewportSet(SDL_Renderer *renderer)
+{
+    CHECK_RENDERER_MAGIC(renderer, -1);
+
+	if (renderer->view->viewport.w >= 0 &&
+		renderer->view->viewport.h >= 0) {
+		return SDL_TRUE;
+	}
+	return SDL_FALSE;
+}
+
 static void GetRenderViewportSize(SDL_Renderer *renderer, SDL_FRect *rect)
 {
     rect->x = 0.0f;