SDL: testshape: use SDL_test to create multiple windows

From 7484d02a2e839652ab73857fb250f5ed8f4140d5 Mon Sep 17 00:00:00 2001
From: Anonymous Maarten <[EMAIL REDACTED]>
Date: Mon, 27 Nov 2023 21:20:01 +0100
Subject: [PATCH] testshape: use SDL_test to create multiple windows

---
 test/testshape.c | 150 +++++++++++++++++++++++------------------------
 1 file changed, 73 insertions(+), 77 deletions(-)

diff --git a/test/testshape.c b/test/testshape.c
index e136bb28bc38..23fc5cb42dbc 100644
--- a/test/testshape.c
+++ b/test/testshape.c
@@ -50,7 +50,9 @@ typedef struct SDL_WindowShapeMode
 typedef struct LoadedPicture
 {
     SDL_Surface *surface;
-    SDL_Texture *texture;
+    int num_textures;
+    SDL_Texture **textures;
+    SDL_Texture **shape_textures;
     SDL_WindowShapeMode mode;
     const char *name;
     struct LoadedPicture *next;
@@ -59,7 +61,6 @@ typedef struct LoadedPicture
 static Uint8 *g_bitmap = NULL;
 static int g_bitmap_w = 0, g_bitmap_h = 0;
 static SDL_Surface *g_shape_surface = NULL;
-static SDL_Texture *g_shape_texture = NULL;
 
 static void log_usage(SDLTest_CommonState *state, char *progname) {
     static const char *options[] = { "sample1.bmp [sample2.bmp [sample3.bmp ...]]", NULL };
@@ -115,16 +116,23 @@ static void SDL_CalculateShapeBitmap(SDL_WindowShapeMode mode, SDL_Surface *shap
     }
 }
 
-static int SDL3_SetWindowShape(SDL_Window *window, SDL_Surface *shape, SDL_WindowShapeMode *shape_mode)
+static int SDL3_SetWindowShape(LoadedPicture *picture, SDL_WindowShapeMode *shape_mode)
 {
     if (g_bitmap) {
         SDL_free(g_bitmap);
         g_bitmap = NULL;
     }
 
-    if (g_shape_texture) {
-        SDL_DestroyTexture(g_shape_texture);
-        g_shape_texture = NULL;
+    if (!picture) {
+        return SDL_SetError("picture");
+    }
+
+    if (picture->shape_textures[0]) {
+        int i;
+        for (i = 0; i < picture->num_textures; i++) {
+            SDL_DestroyTexture(picture->shape_textures[i]);
+            picture->shape_textures[i] = NULL;
+        }
     }
 
     if (g_shape_surface) {
@@ -132,22 +140,18 @@ static int SDL3_SetWindowShape(SDL_Window *window, SDL_Surface *shape, SDL_Windo
         g_shape_surface = NULL;
     }
 
-    if (!shape) {
-        return SDL_SetError("shape");
-    }
-
     if (!shape_mode) {
         return SDL_SetError("shape_mode");
     }
 
-    g_bitmap_w = shape->w;
-    g_bitmap_h = shape->h;
-    g_bitmap = (Uint8*) SDL_malloc(shape->w * shape->h);
+    g_bitmap_w = picture->surface->w;
+    g_bitmap_h = picture->surface->h;
+    g_bitmap = (Uint8*) SDL_malloc(picture->surface->w * picture->surface->h);
     if (!g_bitmap) {
         return -1;
     }
 
-    SDL_CalculateShapeBitmap(*shape_mode, shape, g_bitmap, 1);
+    SDL_CalculateShapeBitmap(*shape_mode, picture->surface, g_bitmap, 1);
 
     g_shape_surface = SDL_CreateSurface(g_bitmap_w, g_bitmap_h, SDL_PIXELFORMAT_ABGR8888);
     if (g_shape_surface) {
@@ -169,14 +173,14 @@ static int SDL3_SetWindowShape(SDL_Window *window, SDL_Surface *shape, SDL_Windo
     return 0;
 }
 
-static void render(SDL_Renderer *renderer, SDL_Texture *texture)
+static void render(int index, SDL_Renderer *renderer, LoadedPicture *picture)
 {
     /* Clear render-target to blue. */
     SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0xff, 0xff);
     SDL_RenderClear(renderer);
 
     /* Render the texture. */
-    SDL_RenderTexture(renderer, texture, NULL, NULL);
+    SDL_RenderTexture(renderer, picture->textures[index], NULL, NULL);
 
     /* Apply the shape */
     if (g_shape_surface) {
@@ -200,19 +204,19 @@ static void render(SDL_Renderer *renderer, SDL_Texture *texture)
                 SDL_SetRenderDrawColor(renderer, r, g, b, a);
             }
         } else {
-            if (!g_shape_texture) {
+            if (!picture->shape_textures[index]) {
                 SDL_BlendMode bm;
 
-                g_shape_texture = SDL_CreateTextureFromSurface(renderer, g_shape_surface);
+                picture->shape_textures[index] = SDL_CreateTextureFromSurface(renderer, g_shape_surface);
 
                 /* if Alpha is 0, set all to 0, else leave unchanged. */
                 bm = SDL_ComposeCustomBlendMode(
                         SDL_BLENDFACTOR_ZERO, SDL_BLENDFACTOR_SRC_ALPHA, SDL_BLENDOPERATION_ADD,
                         SDL_BLENDFACTOR_ZERO, SDL_BLENDFACTOR_SRC_ALPHA, SDL_BLENDOPERATION_ADD);
 
-                SDL_SetTextureBlendMode(g_shape_texture, bm);
+                SDL_SetTextureBlendMode(picture->shape_textures[index], bm);
             }
-            SDL_RenderTexture(renderer, g_shape_texture, NULL, NULL);
+            SDL_RenderTexture(renderer, picture->shape_textures[index], NULL, NULL);
         }
     }
 
@@ -226,13 +230,11 @@ int main(int argc, char **argv)
     LoadedPicture *picture_linked_list = NULL;
     LoadedPicture **pictures = NULL;
     int i;
+    int j;
     const SDL_DisplayMode *mode;
     SDL_PixelFormat *format = NULL;
-    SDL_Window *window = NULL;
-    SDL_Renderer *renderer = NULL;
     SDL_Color black = { 0, 0, 0, 0xff };
-    SDL_Event event;
-    int should_exit = 0;
+    int done = 0;
     int current_picture;
     int button_down;
     Uint32 pixelFormat = 0;
@@ -241,11 +243,14 @@ int main(int argc, char **argv)
     int rc;
 
     /* Initialize test framework */
-    state = SDLTest_CommonCreateState(argv, 0);
+    state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
     if (!state) {
         return 1;
     }
 
+    state->window_flags |= SDL_WINDOW_TRANSPARENT;
+    state->window_flags &= ~SDL_WINDOW_RESIZABLE;
+
     rc = 0;
 
     /* SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software"); */
@@ -277,14 +282,16 @@ int main(int argc, char **argv)
         i += consumed;
     }
     if (!num_pictures) {
-        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Shape requires at least one bitmap file as argument.");
+        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "testshape requires at least one bitmap file as argument.");
         log_usage(state, argv[0]);
-        exit(-1);
+        rc = -1;
+        goto ret;
     }
 
-    if (SDL_Init(SDL_INIT_VIDEO) == -1) {
+    if (!SDLTest_CommonInit(state)) {
         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not initialize SDL video.");
-        exit(-2);
+        rc = -2;
+        goto ret;
     }
 
     mode = SDL_GetDesktopDisplayMode(SDL_GetPrimaryDisplay());
@@ -323,48 +330,42 @@ int main(int argc, char **argv)
         }
     }
 
-    window = SDL_CreateWindow("SDL_Shape test", SHAPED_WINDOW_DIMENSION, SHAPED_WINDOW_DIMENSION, SDL_WINDOW_TRANSPARENT);
-    if (!window) {
-        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not create shaped window for SDL_Shape.");
-        rc = -4;
-        goto ret;
-    }
-    renderer = SDL_CreateRenderer(window, NULL, 0);
-    if (!renderer) {
-        SDL_DestroyWindow(window);
-        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not create rendering context for SDL_Shape window.");
-        rc = -4;
-        goto ret;
-    }
-
     for (i = 0; i < num_pictures; i++) {
-        pictures[i]->texture = NULL;
-    }
-    for (i = 0; i < num_pictures; i++) {
-        pictures[i]->texture = SDL_CreateTextureFromSurface(renderer, pictures[i]->surface);
-        if (pictures[i]->texture == NULL) {
-            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not create texture for SDL_shape.");
-            rc = -6;
+        pictures[i]->textures = SDL_calloc(state->num_windows, sizeof(SDL_Texture *));
+        pictures[i]->shape_textures = SDL_calloc(state->num_windows, sizeof(SDL_Texture *));
+        if (!pictures[i]->textures || !pictures[i]->shape_textures) {
+            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not create textures array(s).");
+            rc = -4;
             goto ret;
         }
+
+        for (j = 0; j < state->num_windows; j++) {
+            pictures[i]->textures[j] = SDL_CreateTextureFromSurface(state->renderers[j], pictures[i]->surface);
+            if (!pictures[i]->textures[j]) {
+                SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not create textures for SDL_shape.");
+                rc = -5;
+                goto ret;
+            }
+        }
     }
 
-    should_exit = 0;
+    done = 0;
     current_picture = 0;
     button_down = 0;
     SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Changing to shaped bmp: %s", pictures[current_picture]->name);
-    SDL_QueryTexture(pictures[current_picture]->texture, &pixelFormat, &access, &w, &h);
-    /* We want to set the window size in pixels */
-    SDL_SetWindowSize(window, (int)SDL_ceilf(w / mode->pixel_density), (int)SDL_ceilf(h / mode->pixel_density));
-    SDL3_SetWindowShape(window, pictures[current_picture]->surface, &pictures[current_picture]->mode);
-    while (should_exit == 0) {
+    for (i = 0; i < state->num_windows; i++) {
+        SDL_QueryTexture(pictures[current_picture]->textures[i], &pixelFormat, &access, &w, &h);
+        /* We want to set the window size in pixels */
+        SDL_SetWindowSize(state->windows[i], (int)SDL_ceilf(w / mode->pixel_density), (int)SDL_ceilf(h / mode->pixel_density));
+    }
+    SDL3_SetWindowShape(pictures[current_picture], &pictures[current_picture]->mode);
+    while (!done) {
+        SDL_Event event;
+
         while (SDL_PollEvent(&event)) {
+            SDLTest_CommonEvent(state, &event, &done);
             if (event.type == SDL_EVENT_KEY_DOWN) {
                 button_down = 1;
-                if (event.key.keysym.sym == SDLK_ESCAPE) {
-                    should_exit = 1;
-                    break;
-                }
             }
             if (button_down && event.type == SDL_EVENT_KEY_UP) {
                 button_down = 0;
@@ -373,16 +374,16 @@ int main(int argc, char **argv)
                     current_picture = 0;
                 }
                 SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Changing to shaped bmp: %s", pictures[current_picture]->name);
-                SDL_QueryTexture(pictures[current_picture]->texture, &pixelFormat, &access, &w, &h);
-                SDL_SetWindowSize(window, (int)SDL_ceilf(w / mode->pixel_density), (int)SDL_ceilf(h / mode->pixel_density));
-                SDL3_SetWindowShape(window, pictures[current_picture]->surface, &pictures[current_picture]->mode);
-            }
-            if (event.type == SDL_EVENT_QUIT) {
-                should_exit = 1;
-                break;
+                for (i = 0; i < state->num_windows; i++) {
+                    SDL_QueryTexture(pictures[current_picture]->textures[i], &pixelFormat, &access, &w, &h);
+                    SDL_SetWindowSize(state->windows[i], (int)SDL_ceilf(w / mode->pixel_density),(int)SDL_ceilf(h / mode->pixel_density));
+                    SDL3_SetWindowShape(pictures[current_picture], &pictures[current_picture]->mode);
+                }
             }
         }
-        render(renderer, pictures[current_picture]->texture);
+        for (i = 0; i < state->num_windows; i++) {
+            render(i, state->renderers[i], pictures[current_picture]);
+        }
         SDL_Delay(10);
     }
 
@@ -390,20 +391,16 @@ int main(int argc, char **argv)
     /* Free the textures + original surfaces backing the textures. */
     for (pic_i = picture_linked_list; pic_i; ) {
         LoadedPicture *next = pic_i->next;
-        if (pic_i->texture) {
-            SDL_DestroyTexture(pic_i->texture);
+        for (j = 0; j < state->num_windows; j++) {
+            SDL_DestroyTexture(pic_i->textures[i]);
         }
+        SDL_free(pic_i->textures);
         SDL_DestroySurface(pic_i->surface);
         SDL_free(pic_i);
         pic_i = next;
     }
     SDL_free(pictures);
 
-    /* Destroy the renderer. */
-    SDL_DestroyRenderer(renderer);
-    /* Destroy the window. */
-    SDL_DestroyWindow(window);
-
     if (g_bitmap) {
         SDL_free(g_bitmap);
         g_bitmap = NULL;
@@ -413,8 +410,7 @@ int main(int argc, char **argv)
         g_shape_surface = NULL;
     }
 
-    SDL_Quit();
-    SDLTest_CommonDestroyState(state);
+    SDLTest_CommonQuit(state);
 
     return rc;
 }