SDL: shape: Free platform-specific shaped window data.

From c8d20f96ba966c8624c973da44214524b764c929 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Tue, 25 Oct 2022 23:13:34 -0400
Subject: [PATCH] shape: Free platform-specific shaped window data.

Fixes #2128.
---
 src/video/cocoa/SDL_cocoawindow.m     |  6 ++++++
 src/video/os2/SDL_os2video.c          | 11 +++++++++++
 src/video/windows/SDL_windowsshape.c  | 10 +++++++---
 src/video/windows/SDL_windowswindow.c | 13 +++++++++++++
 src/video/x11/SDL_x11window.c         | 10 ++++++++++
 5 files changed, 47 insertions(+), 3 deletions(-)

diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m
index ec223c6d3853..eea7f981a662 100644
--- a/src/video/cocoa/SDL_cocoawindow.m
+++ b/src/video/cocoa/SDL_cocoawindow.m
@@ -2370,6 +2370,12 @@ - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
         }
 
         #endif /* SDL_VIDEO_OPENGL */
+
+        if (window->shaper) {
+            CFBridgingRelease(window->shaper->driverdata);
+            SDL_free(window->shaper);
+            window->shaper = NULL;
+        }
     }
     window->driverdata = NULL;
 }}
diff --git a/src/video/os2/SDL_os2video.c b/src/video/os2/SDL_os2video.c
index a9599c8f3cc0..599384edf6c4 100644
--- a/src/video/os2/SDL_os2video.c
+++ b/src/video/os2/SDL_os2video.c
@@ -914,6 +914,17 @@ static void OS2_DestroyWindow(_THIS, SDL_Window * window)
     if (pWinData == NULL)
         return;
 
+    if (pWinData->hrgnShape != NULLHANDLE) {
+        HPS hps = WinGetPS(pWinData->hwnd);
+        GpiDestroyRegion(hps, pWinData->hrgnShape);
+        WinReleasePS(hps);
+    }
+
+    if (window->shaper) {
+        SDL_free(window->shaper);
+        window->shaper = NULL;
+    }
+
     if (pWinData->fnUserWndProc == NULL) {
         /* Window was created by SDL (OS2_CreateWindow()),
          * not by user (OS2_CreateWindowFrom()) */
diff --git a/src/video/windows/SDL_windowsshape.c b/src/video/windows/SDL_windowsshape.c
index ef716a506d61..919076f9a215 100644
--- a/src/video/windows/SDL_windowsshape.c
+++ b/src/video/windows/SDL_windowsshape.c
@@ -36,11 +36,15 @@ Win32_CreateShaper(SDL_Window * window) {
     result->hasshape = SDL_FALSE;
     result->driverdata = (SDL_ShapeData*)SDL_malloc(sizeof(SDL_ShapeData));
     ((SDL_ShapeData*)result->driverdata)->mask_tree = NULL;
-    /* Put some driver-data here. */
     window->shaper = result;
+    /* Put some driver-data here. */
     resized_properly = Win32_ResizeWindowShape(window);
-    if (resized_properly != 0)
-            return NULL;
+    if (resized_properly != 0) {
+        SDL_free(result->driverdata);
+        SDL_free(result);
+        window->shaper = NULL;
+        return NULL;
+    }
 
     return result;
 }
diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c
index 77417b28d3fe..488b6fe1a52d 100644
--- a/src/video/windows/SDL_windowswindow.c
+++ b/src/video/windows/SDL_windowswindow.c
@@ -34,6 +34,7 @@
 
 #include "SDL_windowsvideo.h"
 #include "SDL_windowswindow.h"
+#include "SDL_windowsshape.h"
 #include "SDL_hints.h"
 #include "SDL_timer.h"
 
@@ -1168,6 +1169,18 @@ WIN_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
 void
 WIN_DestroyWindow(_THIS, SDL_Window * window)
 {
+    if (window->shaper) {
+        SDL_ShapeData *shapedata = (SDL_ShapeData *) window->shaper->driverdata;
+        if (shapedata) {
+            if (shapedata->mask_tree) {
+                SDL_FreeShapeTree(&shapedata->mask_tree);
+            }
+            SDL_free(shapedata);
+        }
+        SDL_free(window->shaper);
+        window->shaper = NULL;
+    }
+
     CleanupWindowData(_this, window);
 }
 
diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c
index bfba775f200a..770116bb0635 100644
--- a/src/video/x11/SDL_x11window.c
+++ b/src/video/x11/SDL_x11window.c
@@ -1686,6 +1686,16 @@ X11_DestroyWindow(_THIS, SDL_Window * window)
 {
     SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
 
+    if (window->shaper) {
+        SDL_ShapeData *shapedata = (SDL_ShapeData *) window->shaper->driverdata;
+        if (shapedata) {
+            SDL_free(shapedata->bitmap);
+            SDL_free(shapedata);
+        }
+        SDL_free(window->shaper);
+        window->shaper = NULL;
+    }
+
     if (data) {
         SDL_VideoData *videodata = (SDL_VideoData *) data->videodata;
         Display *display = videodata->display;