From 25cd57ca8d5de4dc0871852f100732d7525a26ab Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sun, 19 Oct 2025 13:56:01 -0700
Subject: [PATCH] Added IMG_CreateAnimatedCursor()
---
CMakeLists.txt | 2 +-
include/SDL3_image/SDL_image.h | 20 ++++++++++++++++++++
src/IMG.c | 28 ++++++++++++++++++++++++++++
src/SDL_image.sym | 1 +
4 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 69db9866..c888178f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -10,7 +10,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
set(MAJOR_VERSION 3)
set(MINOR_VERSION 3)
set(MICRO_VERSION 0)
-set(SDL_REQUIRED_VERSION 3.2.6)
+set(SDL_REQUIRED_VERSION 3.3.0)
project(SDL3_image
LANGUAGES C
diff --git a/include/SDL3_image/SDL_image.h b/include/SDL3_image/SDL_image.h
index 0254b2b9..f3a8d1b2 100644
--- a/include/SDL3_image/SDL_image.h
+++ b/include/SDL3_image/SDL_image.h
@@ -2222,6 +2222,7 @@ typedef struct IMG_Animation
*
* \since This function is available since SDL_image 3.0.0.
*
+ * \sa IMG_CreateAnimatedCursor
* \sa IMG_LoadAnimation_IO
* \sa IMG_LoadAnimationTyped_IO
* \sa IMG_LoadAPNGAnimation_IO
@@ -2249,6 +2250,7 @@ extern SDL_DECLSPEC IMG_Animation * SDLCALL IMG_LoadAnimation(const char *file);
*
* \since This function is available since SDL_image 3.0.0.
*
+ * \sa IMG_CreateAnimatedCursor
* \sa IMG_LoadAnimation
* \sa IMG_LoadAnimationTyped_IO
* \sa IMG_LoadAPNGAnimation_IO
@@ -2283,6 +2285,7 @@ extern SDL_DECLSPEC IMG_Animation * SDLCALL IMG_LoadAnimation_IO(SDL_IOStream *s
*
* \since This function is available since SDL_image 3.0.0.
*
+ * \sa IMG_CreateAnimatedCursor
* \sa IMG_LoadAnimation
* \sa IMG_LoadAnimation_IO
* \sa IMG_LoadAPNGAnimation_IO
@@ -2410,6 +2413,23 @@ extern SDL_DECLSPEC IMG_Animation * SDLCALL IMG_LoadGIFAnimation_IO(SDL_IOStream
*/
extern SDL_DECLSPEC IMG_Animation * SDLCALL IMG_LoadWEBPAnimation_IO(SDL_IOStream *src);
+/**
+ * Create an animated cursor from an animation.
+ *
+ * \param anim an animation to use to create an animated cursor.
+ * \param hot_x the x position of the cursor hot spot.
+ * \param hot_y the y position of the cursor hot spot.
+ * \returns the new cursor on success or NULL on failure; call SDL_GetError()
+ * for more information.
+ *
+ * \since This function is available since SDL_image 3.4.0.
+ *
+ * \sa IMG_LoadAnimation
+ * \sa IMG_LoadAnimation_IO
+ * \sa IMG_LoadAnimationTyped_IO
+ */
+extern SDL_DECLSPEC SDL_Cursor * SDLCALL IMG_CreateAnimatedCursor(IMG_Animation *anim, int hot_x, int hot_y);
+
/**
* An object representing the encoder context.
*/
diff --git a/src/IMG.c b/src/IMG.c
index 8572fcd9..8809de7b 100644
--- a/src/IMG.c
+++ b/src/IMG.c
@@ -321,6 +321,34 @@ IMG_Animation *IMG_LoadAnimationTyped_IO(SDL_IOStream *src, bool closeio, const
return NULL;
}
+SDL_Cursor *IMG_CreateAnimatedCursor(IMG_Animation *anim, int hot_x, int hot_y)
+{
+ int i;
+ SDL_CursorFrameInfo *frames;
+ SDL_Cursor *cursor;
+
+ if (!anim) {
+ SDL_InvalidParamError("anim");
+ return NULL;
+ }
+
+ frames = (SDL_CursorFrameInfo *)SDL_calloc(anim->count, sizeof(*frames));
+ if (!frames) {
+ return NULL;
+ }
+
+ for (i = 0; i < anim->count; ++i) {
+ frames[i].surface = anim->frames[i];
+ frames[i].duration = (Uint32)anim->delays[i];
+ }
+
+ cursor = SDL_CreateAnimatedCursor(frames, anim->count, hot_x, hot_y);
+
+ SDL_free(frames);
+
+ return cursor;
+}
+
void IMG_FreeAnimation(IMG_Animation *anim)
{
if (anim) {
diff --git a/src/SDL_image.sym b/src/SDL_image.sym
index 96234f4e..b23a914e 100644
--- a/src/SDL_image.sym
+++ b/src/SDL_image.sym
@@ -85,5 +85,6 @@ SDL3_image_0.0.0 {
IMG_GetAnimationDecoderProperties;
IMG_GetAnimationDecoderStatus;
IMG_GetClipboardImage;
+ IMG_CreateAnimatedCursor;
local: *;
};