Bläddra i källkod

Added SDL_CursorData for internal cursor data

Sam Lantinga 8 månader sedan
förälder
incheckning
b8f3cd0a10

+ 3 - 1
src/events/SDL_mouse_c.h

@@ -29,10 +29,12 @@
 /* The default mouse input device, for platforms that don't have multiple mice */
 #define SDL_DEFAULT_MOUSE_ID    1
 
+typedef struct SDL_CursorData SDL_CursorData;
+
 struct SDL_Cursor
 {
     struct SDL_Cursor *next;
-    void *internal;
+    SDL_CursorData *internal;
 };
 
 typedef struct

+ 5 - 6
src/video/android/SDL_androidmouse.c

@@ -41,12 +41,11 @@
 #define BUTTON_BACK       8
 #define BUTTON_FORWARD    16
 
-typedef struct
+struct SDL_CursorData
 {
     int custom_cursor;
     int system_cursor;
-
-} SDL_AndroidCursorData;
+};
 
 /* Last known Android mouse button state (includes all buttons) */
 static int last_state;
@@ -60,7 +59,7 @@ static SDL_Cursor *Android_WrapCursor(int custom_cursor, int system_cursor)
 
     cursor = SDL_calloc(1, sizeof(*cursor));
     if (cursor) {
-        SDL_AndroidCursorData *data = (SDL_AndroidCursorData *)SDL_calloc(1, sizeof(*data));
+        SDL_CursorData *data = (SDL_CursorData *)SDL_calloc(1, sizeof(*data));
         if (data) {
             data->custom_cursor = custom_cursor;
             data->system_cursor = system_cursor;
@@ -104,7 +103,7 @@ static SDL_Cursor *Android_CreateSystemCursor(SDL_SystemCursor id)
 
 static void Android_FreeCursor(SDL_Cursor *cursor)
 {
-    SDL_AndroidCursorData *data = (SDL_AndroidCursorData *)cursor->internal;
+    SDL_CursorData *data = cursor->internal;
     if (data->custom_cursor != 0) {
         Android_JNI_DestroyCustomCursor(data->custom_cursor);
     }
@@ -139,7 +138,7 @@ static int Android_ShowCursor(SDL_Cursor *cursor)
         cursor = Android_CreateEmptyCursor();
     }
     if (cursor) {
-        SDL_AndroidCursorData *data = (SDL_AndroidCursorData *)cursor->internal;
+        SDL_CursorData *data = cursor->internal;
         if (data->custom_cursor) {
             if (!Android_JNI_SetCustomCursor(data->custom_cursor)) {
                 return SDL_Unsupported();

+ 1 - 1
src/video/cocoa/SDL_cocoamouse.m

@@ -232,7 +232,7 @@ static SDL_Cursor *Cocoa_CreateSystemCursor(SDL_SystemCursor id)
 static void Cocoa_FreeCursor(SDL_Cursor *cursor)
 {
     @autoreleasepool {
-        CFBridgingRelease(cursor->internal);
+        CFBridgingRelease((void *)cursor->internal);
         SDL_free(cursor);
     }
 }

+ 7 - 7
src/video/emscripten/SDL_emscriptenmouse.c

@@ -43,10 +43,10 @@
 
 static SDL_Cursor *Emscripten_CreateCursorFromString(const char *cursor_str, SDL_bool is_custom)
 {
-    Emscripten_CursorData *curdata;
+    SDL_CursorData *curdata;
     SDL_Cursor *cursor = SDL_calloc(1, sizeof(SDL_Cursor));
     if (cursor) {
-        curdata = (Emscripten_CursorData *)SDL_calloc(1, sizeof(*curdata));
+        curdata = (SDL_CursorData *)SDL_calloc(1, sizeof(*curdata));
         if (!curdata) {
             SDL_free(cursor);
             return NULL;
@@ -125,9 +125,9 @@ static SDL_Cursor *Emscripten_CreateSystemCursor(SDL_SystemCursor id)
 
 static void Emscripten_FreeCursor(SDL_Cursor *cursor)
 {
-    Emscripten_CursorData *curdata;
+    SDL_CursorData *curdata;
     if (cursor) {
-        curdata = (Emscripten_CursorData *)cursor->internal;
+        curdata = cursor->internal;
 
         if (curdata) {
             if (curdata->is_custom) {
@@ -142,10 +142,10 @@ static void Emscripten_FreeCursor(SDL_Cursor *cursor)
 
 static int Emscripten_ShowCursor(SDL_Cursor *cursor)
 {
-    Emscripten_CursorData *curdata;
+    SDL_CursorData *curdata;
     if (SDL_GetMouseFocus() != NULL) {
         if (cursor && cursor->internal) {
-            curdata = (Emscripten_CursorData *)cursor->internal;
+            curdata = cursor->internal;
 
             if (curdata->system_cursor) {
                 /* *INDENT-OFF* */ /* clang-format off */
@@ -207,7 +207,7 @@ void Emscripten_InitMouse(void)
     SDL_SetDefaultCursor(Emscripten_CreateDefaultCursor());
 }
 
-void Emscripten_FiniMouse(void)
+void Emscripten_QuitMouse(void)
 {
 }
 

+ 4 - 7
src/video/emscripten/SDL_emscriptenmouse.h

@@ -22,16 +22,13 @@
 #ifndef SDL_emscriptenmouse_h_
 #define SDL_emscriptenmouse_h_
 
-typedef struct _Emscripten_CursorData
+struct SDL_CursorData
 {
     const char *system_cursor;
     SDL_bool is_custom;
-} Emscripten_CursorData;
+};
 
-extern void
-Emscripten_InitMouse();
-
-extern void
-Emscripten_FiniMouse();
+extern void Emscripten_InitMouse(void);
+extern void Emscripten_QuitMouse(void);
 
 #endif /* SDL_emscriptenmouse_h_ */

+ 1 - 1
src/video/emscripten/SDL_emscriptenvideo.c

@@ -152,7 +152,7 @@ static int Emscripten_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *d
 
 static void Emscripten_VideoQuit(SDL_VideoDevice *_this)
 {
-    Emscripten_FiniMouse();
+    Emscripten_QuitMouse();
 }
 
 static int Emscripten_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect)

+ 28 - 18
src/video/haiku/SDL_bvideo.cc

@@ -120,6 +120,26 @@ void HAIKU_DeleteDevice(SDL_VideoDevice * device)
     SDL_free(device);
 }
 
+struct SDL_CursorData
+{
+    BCursor *cursor;
+};
+
+static SDL_Cursor *HAIKU_CreateCursorAndData(BCursor *bcursor)
+{
+    SDL_Cursor *cursor = (SDL_Cursor *)SDL_calloc(1, sizeof(*cursor));
+    if (cursor) {
+        SDL_CursorData *data = (SDL_CursorData *)SDL_calloc(1, sizeof(*data));
+        if (!data) {
+            SDL_free(cursor);
+            return NULL;
+        }
+        data->cursor = bcursor;
+        cursor->internal = data;
+    }
+    return cursor;
+}
+
 static SDL_Cursor * HAIKU_CreateSystemCursor(SDL_SystemCursor id)
 {
     BCursorID cursorId = B_CURSOR_ID_SYSTEM_DEFAULT;
@@ -153,12 +173,7 @@ static SDL_Cursor * HAIKU_CreateSystemCursor(SDL_SystemCursor id)
             return NULL;
     }
 
-    SDL_Cursor *cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor));
-    if (cursor) {
-        cursor->internal = (void *)new BCursor(cursorId);
-    }
-
-    return cursor;
+    return HAIKU_CreateCursorAndData(new BCursor(cursorId));
 }
 
 static SDL_Cursor * HAIKU_CreateDefaultCursor()
@@ -168,15 +183,17 @@ static SDL_Cursor * HAIKU_CreateDefaultCursor()
 
 static void HAIKU_FreeCursor(SDL_Cursor * cursor)
 {
-    if (cursor->internal) {
-        delete (BCursor*) cursor->internal;
+    SDL_CursorData *data = cursor->internal;
+
+    if (data) {
+        delete data->cursor;
     }
+    SDL_free(data);
     SDL_free(cursor);
 }
 
 static SDL_Cursor * HAIKU_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
 {
-    SDL_Cursor *cursor;
     SDL_Surface *converted;
 
     converted = SDL_ConvertSurface(surface, SDL_PIXELFORMAT_ARGB8888);
@@ -188,14 +205,7 @@ static SDL_Cursor * HAIKU_CreateCursor(SDL_Surface * surface, int hot_x, int hot
 	cursorBitmap->SetBits(converted->pixels, converted->h * converted->pitch, 0, B_RGBA32);
     SDL_DestroySurface(converted);
 
-    cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor));
-    if (cursor) {
-        cursor->internal = (void *)new BCursor(cursorBitmap, BPoint(hot_x, hot_y));
-    } else {
-        return NULL;
-    }
-
-    return cursor;
+    return HAIKU_CreateCursorAndData(new BCursor(cursorBitmap, BPoint(hot_x, hot_y)));
 }
 
 static int HAIKU_ShowCursor(SDL_Cursor *cursor)
@@ -207,7 +217,7 @@ static int HAIKU_ShowCursor(SDL_Cursor *cursor)
 	}
 
 	if (cursor) {
-		BCursor *hCursor = (BCursor*)cursor->internal;
+		BCursor *hCursor = cursor->internal->cursor;
 		be_app->SetCursor(hCursor);
 	} else {
 		BCursor *hCursor = new BCursor(B_CURSOR_ID_NO_CURSOR);

+ 5 - 5
src/video/kmsdrm/SDL_kmsdrmmouse.c

@@ -134,7 +134,7 @@ static int KMSDRM_RemoveCursorFromBO(SDL_VideoDisplay *display)
 static int KMSDRM_DumpCursorToBO(SDL_VideoDisplay *display, SDL_Cursor *cursor)
 {
     SDL_DisplayData *dispdata = display->internal;
-    KMSDRM_CursorData *curdata = (KMSDRM_CursorData *)cursor->internal;
+    SDL_CursorData *curdata = cursor->internal;
     SDL_VideoDevice *video_device = SDL_GetVideoDevice();
     SDL_VideoData *viddata = video_device->internal;
 
@@ -206,11 +206,11 @@ cleanup:
 /* This is only for freeing the SDL_cursor.*/
 static void KMSDRM_FreeCursor(SDL_Cursor *cursor)
 {
-    KMSDRM_CursorData *curdata;
+    SDL_CursorData *curdata;
 
     /* Even if the cursor is not ours, free it. */
     if (cursor) {
-        curdata = (KMSDRM_CursorData *)cursor->internal;
+        curdata = cursor->internal;
         /* Free cursor buffer */
         if (curdata->buffer) {
             SDL_free(curdata->buffer);
@@ -229,7 +229,7 @@ static void KMSDRM_FreeCursor(SDL_Cursor *cursor)
    in dispata) is destroyed and recreated when we recreate windows, etc. */
 static SDL_Cursor *KMSDRM_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
 {
-    KMSDRM_CursorData *curdata;
+    SDL_CursorData *curdata;
     SDL_Cursor *cursor, *ret;
 
     curdata = NULL;
@@ -239,7 +239,7 @@ static SDL_Cursor *KMSDRM_CreateCursor(SDL_Surface *surface, int hot_x, int hot_
     if (!cursor) {
         goto cleanup;
     }
-    curdata = (KMSDRM_CursorData *)SDL_calloc(1, sizeof(*curdata));
+    curdata = (SDL_CursorData *)SDL_calloc(1, sizeof(*curdata));
     if (!curdata) {
         goto cleanup;
     }

+ 2 - 2
src/video/kmsdrm/SDL_kmsdrmmouse.h

@@ -29,7 +29,7 @@
 #define MAX_CURSOR_W 512
 #define MAX_CURSOR_H 512
 
-typedef struct KMSDRM_CursorData
+struct SDL_CursorData
 {
     int hot_x, hot_y;
     int w, h;
@@ -41,7 +41,7 @@ typedef struct KMSDRM_CursorData
     size_t buffer_size;
     size_t buffer_pitch;
 
-} KMSDRM_CursorData;
+};
 
 extern void KMSDRM_InitMouse(SDL_VideoDevice *_this, SDL_VideoDisplay *display);
 extern void KMSDRM_QuitMouse(SDL_VideoDevice *_this);

+ 9 - 9
src/video/raspberry/SDL_rpimouse.c

@@ -55,7 +55,7 @@ static SDL_Cursor *RPI_CreateDefaultCursor(void)
 /* Create a cursor from a surface */
 static SDL_Cursor *RPI_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
 {
-    RPI_CursorData *curdata;
+    SDL_CursorData *curdata;
     SDL_Cursor *cursor;
     int ret;
     VC_RECT_T dst_rect;
@@ -68,7 +68,7 @@ static SDL_Cursor *RPI_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
     if (!cursor) {
         return NULL;
     }
-    curdata = (RPI_CursorData *)SDL_calloc(1, sizeof(*curdata));
+    curdata = (SDL_CursorData *)SDL_calloc(1, sizeof(*curdata));
     if (!curdata) {
         SDL_free(cursor);
         return NULL;
@@ -102,7 +102,7 @@ static int RPI_ShowCursor(SDL_Cursor *cursor)
 {
     int ret;
     DISPMANX_UPDATE_HANDLE_T update;
-    RPI_CursorData *curdata;
+    SDL_CursorData *curdata;
     VC_RECT_T src_rect, dst_rect;
     SDL_Mouse *mouse;
     SDL_DisplayData *data;
@@ -117,7 +117,7 @@ static int RPI_ShowCursor(SDL_Cursor *cursor)
 
     if (cursor != global_cursor) {
         if (global_cursor) {
-            curdata = (RPI_CursorData *)global_cursor->internal;
+            curdata = global_cursor->internal;
             if (curdata && curdata->element > DISPMANX_NO_HANDLE) {
                 update = vc_dispmanx_update_start(0);
                 SDL_assert(update);
@@ -135,7 +135,7 @@ static int RPI_ShowCursor(SDL_Cursor *cursor)
         return 0;
     }
 
-    curdata = (RPI_CursorData *)cursor->internal;
+    curdata = cursor->internal;
     if (!curdata) {
         return -1;
     }
@@ -184,10 +184,10 @@ static void RPI_FreeCursor(SDL_Cursor *cursor)
 {
     int ret;
     DISPMANX_UPDATE_HANDLE_T update;
-    RPI_CursorData *curdata;
+    SDL_CursorData *curdata;
 
     if (cursor) {
-        curdata = (RPI_CursorData *)cursor->internal;
+        curdata = cursor->internal;
 
         if (curdata) {
             if (curdata->element != DISPMANX_NO_HANDLE) {
@@ -215,7 +215,7 @@ static void RPI_FreeCursor(SDL_Cursor *cursor)
 
 static int RPI_WarpMouseGlobalGraphically(float x, float y)
 {
-    RPI_CursorData *curdata;
+    SDL_CursorData *curdata;
     DISPMANX_UPDATE_HANDLE_T update;
     int ret;
     VC_RECT_T dst_rect;
@@ -226,7 +226,7 @@ static int RPI_WarpMouseGlobalGraphically(float x, float y)
         return 0;
     }
 
-    curdata = (RPI_CursorData *)mouse->cur_cursor->internal;
+    curdata = mouse->cur_cursor->internal;
     if (curdata->element == DISPMANX_NO_HANDLE) {
         return 0;
     }

+ 1 - 2
src/video/raspberry/SDL_rpimouse.h

@@ -24,8 +24,7 @@
 
 #include "../SDL_sysvideo.h"
 
-typedef struct _RPI_CursorData RPI_CursorData;
-struct _RPI_CursorData
+struct SDL_CursorData
 {
     DISPMANX_RESOURCE_HANDLE_T resource;
     DISPMANX_ELEMENT_HANDLE_T element;

+ 1 - 1
src/video/wayland/SDL_waylandevents_c.h

@@ -110,7 +110,7 @@ struct SDL_WaylandInput
     struct zwp_input_timestamps_v1 *touch_timestamps;
     SDL_WindowData *pointer_focus;
     SDL_WindowData *keyboard_focus;
-    struct Wayland_CursorData *current_cursor;
+    SDL_CursorData *current_cursor;
     Uint32 keyboard_id;
     Uint32 pointer_id;
     uint32_t pointer_enter_serial;

+ 11 - 11
src/video/wayland/SDL_waylandmouse.c

@@ -66,7 +66,7 @@ typedef struct
     SDL_SystemCursor id;
 } Wayland_SystemCursor;
 
-struct Wayland_CursorData
+struct SDL_CursorData
 {
     union
     {
@@ -287,7 +287,7 @@ struct wl_callback_listener cursor_frame_listener = {
 
 static void cursor_frame_done(void *data, struct wl_callback *cb, uint32_t time)
 {
-    struct Wayland_CursorData *c = (struct Wayland_CursorData *)data;
+    SDL_CursorData *c = (SDL_CursorData *)data;
 
     const Uint64 now = SDL_GetTicks();
     const Uint64 elapsed = (now - c->cursor_data.system.last_frame_time_ms) % c->cursor_data.system.total_duration;
@@ -318,7 +318,7 @@ static void cursor_frame_done(void *data, struct wl_callback *cb, uint32_t time)
     wl_surface_commit(c->surface);
 }
 
-static SDL_bool wayland_get_system_cursor(SDL_VideoData *vdata, struct Wayland_CursorData *cdata, float *scale)
+static SDL_bool wayland_get_system_cursor(SDL_VideoData *vdata, SDL_CursorData *cdata, float *scale)
 {
     struct wl_cursor_theme *theme = NULL;
     struct wl_cursor *cursor;
@@ -422,12 +422,12 @@ static SDL_Cursor *Wayland_CreateCursor(SDL_Surface *surface, int hot_x, int hot
     if (cursor) {
         SDL_VideoDevice *vd = SDL_GetVideoDevice();
         SDL_VideoData *wd = vd->internal;
-        struct Wayland_CursorData *data = SDL_calloc(1, sizeof(struct Wayland_CursorData));
+        SDL_CursorData *data = SDL_calloc(1, sizeof(*data));
         if (!data) {
             SDL_free(cursor);
             return NULL;
         }
-        cursor->internal = (void *)data;
+        cursor->internal = data;
 
         /* Allocate shared memory buffer for this cursor */
         if (Wayland_AllocSHMBuffer(surface->w, surface->h, &data->cursor_data.custom) != 0) {
@@ -458,12 +458,12 @@ static SDL_Cursor *Wayland_CreateSystemCursor(SDL_SystemCursor id)
     SDL_VideoData *data = SDL_GetVideoDevice()->internal;
     SDL_Cursor *cursor = SDL_calloc(1, sizeof(*cursor));
     if (cursor) {
-        struct Wayland_CursorData *cdata = SDL_calloc(1, sizeof(struct Wayland_CursorData));
+        SDL_CursorData *cdata = SDL_calloc(1, sizeof(*cdata));
         if (!cdata) {
             SDL_free(cursor);
             return NULL;
         }
-        cursor->internal = (void *)cdata;
+        cursor->internal = cdata;
 
         /* The surface is only necessary if the cursor shape manager is not present.
          *
@@ -487,7 +487,7 @@ static SDL_Cursor *Wayland_CreateDefaultCursor(void)
     return Wayland_CreateSystemCursor(SDL_SYSTEM_CURSOR_DEFAULT);
 }
 
-static void Wayland_FreeCursorData(struct Wayland_CursorData *d)
+static void Wayland_FreeCursorData(SDL_CursorData *d)
 {
     /* Buffers for system cursors must not be destroyed. */
     if (d->is_system_cursor) {
@@ -516,7 +516,7 @@ static void Wayland_FreeCursor(SDL_Cursor *cursor)
         return;
     }
 
-    Wayland_FreeCursorData((struct Wayland_CursorData *)cursor->internal);
+    Wayland_FreeCursorData(cursor->internal);
 
     SDL_free(cursor->internal);
     SDL_free(cursor);
@@ -615,7 +615,7 @@ static int Wayland_ShowCursor(SDL_Cursor *cursor)
     }
 
     if (cursor) {
-        struct Wayland_CursorData *data = cursor->internal;
+        SDL_CursorData *data = cursor->internal;
 
         /* TODO: High-DPI custom cursors? -flibit */
         if (data->is_system_cursor) {
@@ -764,7 +764,7 @@ static SDL_MouseButtonFlags SDLCALL Wayland_GetGlobalMouseState(float *x, float
 #if 0  /* TODO RECONNECT: See waylandvideo.c for more information! */
 static void Wayland_RecreateCursor(SDL_Cursor *cursor, SDL_VideoData *vdata)
 {
-    Wayland_CursorData *cdata = (Wayland_CursorData *) cursor->internal;
+    SDL_CursorData *cdata = cursor->internal;
 
     /* Probably not a cursor we own */
     if (cdata == NULL) {

+ 40 - 28
src/video/windows/SDL_windowsmouse.c

@@ -30,20 +30,40 @@
 #include "../../events/SDL_mouse_c.h"
 #include "../../joystick/usb_ids.h"
 
+
+struct SDL_CursorData
+{
+    HCURSOR cursor;
+};
+
 DWORD SDL_last_warp_time = 0;
 HCURSOR SDL_cursor = NULL;
 static SDL_Cursor *SDL_blank_cursor = NULL;
 
-static SDL_Cursor *WIN_CreateDefaultCursor(void)
+static SDL_Cursor *WIN_CreateCursorAndData(HCURSOR hcursor)
 {
+    if (!hcursor) {
+        return NULL;
+    }
+
     SDL_Cursor *cursor = (SDL_Cursor *)SDL_calloc(1, sizeof(*cursor));
     if (cursor) {
-        cursor->internal = LoadCursor(NULL, IDC_ARROW);
+        SDL_CursorData *data = (SDL_CursorData *)SDL_calloc(1, sizeof(*data));
+        if (!data) {
+            SDL_free(cursor);
+            return NULL;
+        }
+        data->cursor = hcursor;
+        cursor->internal = data;
     }
-
     return cursor;
 }
 
+static SDL_Cursor *WIN_CreateDefaultCursor(void)
+{
+    return WIN_CreateCursorAndData(LoadCursor(NULL, IDC_ARROW));
+}
+
 static SDL_bool IsMonochromeSurface(SDL_Surface *surface)
 {
     int x, y;
@@ -155,10 +175,9 @@ static HBITMAP CreateMaskBitmap(SDL_Surface *surface, SDL_bool is_monochrome)
     return bitmap;
 }
 
-static SDL_Cursor *WIN_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
+static HCURSOR WIN_CreateHCursor(SDL_Surface *surface, int hot_x, int hot_y)
 {
     HCURSOR hcursor;
-    SDL_Cursor *cursor;
     ICONINFO ii;
     SDL_bool is_monochrome = IsMonochromeSurface(surface);
 
@@ -184,15 +203,16 @@ static SDL_Cursor *WIN_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
         WIN_SetError("CreateIconIndirect()");
         return NULL;
     }
+    return hcursor;
+}
 
-    cursor = (SDL_Cursor *)SDL_calloc(1, sizeof(*cursor));
-    if (cursor) {
-        cursor->internal = hcursor;
-    } else {
-        DestroyCursor(hcursor);
+static SDL_Cursor *WIN_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
+{
+    HCURSOR hcursor = WIN_CreateHCursor(surface, hot_x, hot_y);
+    if (!hcursor) {
+        return NULL;
     }
-
-    return cursor;
+    return WIN_CreateCursorAndData(hcursor);
 }
 
 static SDL_Cursor *WIN_CreateBlankCursor(void)
@@ -208,12 +228,11 @@ static SDL_Cursor *WIN_CreateBlankCursor(void)
 
 static SDL_Cursor *WIN_CreateSystemCursor(SDL_SystemCursor id)
 {
-    SDL_Cursor *cursor;
     LPCTSTR name;
 
     switch (id) {
     default:
-        SDL_assert(0);
+        SDL_assert(!"Unknown system cursor ID");
         return NULL;
     case SDL_SYSTEM_CURSOR_DEFAULT:
         name = IDC_ARROW;
@@ -276,24 +295,17 @@ static SDL_Cursor *WIN_CreateSystemCursor(SDL_SystemCursor id)
         name = IDC_SIZEWE;
         break;
     }
-
-    cursor = (SDL_Cursor *)SDL_calloc(1, sizeof(*cursor));
-    if (cursor) {
-        HCURSOR hcursor;
-
-        hcursor = LoadCursor(NULL, name);
-
-        cursor->internal = hcursor;
-    }
-
-    return cursor;
+    return WIN_CreateCursorAndData(LoadCursor(NULL, name));
 }
 
 static void WIN_FreeCursor(SDL_Cursor *cursor)
 {
-    HCURSOR hcursor = (HCURSOR)cursor->internal;
+    SDL_CursorData *data = cursor->internal;
 
-    DestroyCursor(hcursor);
+    if (data->cursor) {
+        DestroyCursor(data->cursor);
+    }
+    SDL_free(data);
     SDL_free(cursor);
 }
 
@@ -303,7 +315,7 @@ static int WIN_ShowCursor(SDL_Cursor *cursor)
         cursor = SDL_blank_cursor;
     }
     if (cursor) {
-        SDL_cursor = (HCURSOR)cursor->internal;
+        SDL_cursor = cursor->internal->cursor;
     } else {
         SDL_cursor = NULL;
     }

+ 1 - 1
src/video/winrt/SDL_winrtmouse.cpp

@@ -125,7 +125,7 @@ static SDL_Cursor *WINRT_CreateSystemCursor(SDL_SystemCursor id)
         */
         CoreCursor ^ *theCursor = new CoreCursor ^ (nullptr);
         *theCursor = ref new CoreCursor(cursorType, 0);
-        cursor->internal = (void *)theCursor;
+        cursor->internal = (SDL_CursorData *)theCursor;
     }
 
     return cursor;

+ 31 - 22
src/video/x11/SDL_x11mouse.c

@@ -29,6 +29,11 @@
 #include "../SDL_video_c.h"
 #include "../../events/SDL_mouse_c.h"
 
+struct SDL_CursorData
+{
+    Cursor cursor;
+};
+
 /* FIXME: Find a better place to put this... */
 static Cursor x11_empty_cursor = None;
 static SDL_bool x11_cursor_visible = SDL_TRUE;
@@ -69,16 +74,27 @@ static void X11_DestroyEmptyCursor(void)
     }
 }
 
-static SDL_Cursor *X11_CreateDefaultCursor(void)
+static SDL_Cursor *X11_CreateCursorAndData(Cursor x11_cursor)
 {
-    SDL_Cursor *cursor = SDL_calloc(1, sizeof(*cursor));
+    SDL_Cursor *cursor = (SDL_Cursor *)SDL_calloc(1, sizeof(*cursor));
     if (cursor) {
-        /* None is used to indicate the default cursor */
-        cursor->internal = (void *)(uintptr_t)None;
+        SDL_CursorData *data = (SDL_CursorData *)SDL_calloc(1, sizeof(*data));
+        if (!data) {
+            SDL_free(cursor);
+            return NULL;
+        }
+        data->cursor = x11_cursor;
+        cursor->internal = data;
     }
     return cursor;
 }
 
+static SDL_Cursor *X11_CreateDefaultCursor(void)
+{
+    /* None is used to indicate the default cursor */
+    return X11_CreateCursorAndData(None);
+}
+
 #ifdef SDL_VIDEO_DRIVER_X11_XCURSOR
 static Cursor X11_CreateXCursorCursor(SDL_Surface *surface, int hot_x, int hot_y)
 {
@@ -195,22 +211,17 @@ static Cursor X11_CreatePixmapCursor(SDL_Surface *surface, int hot_x, int hot_y)
 
 static SDL_Cursor *X11_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
 {
-    SDL_Cursor *cursor = SDL_calloc(1, sizeof(*cursor));
-    if (cursor) {
-        Cursor x11_cursor = None;
+    Cursor x11_cursor = None;
 
 #ifdef SDL_VIDEO_DRIVER_X11_XCURSOR
-        if (SDL_X11_HAVE_XCURSOR) {
-            x11_cursor = X11_CreateXCursorCursor(surface, hot_x, hot_y);
-        }
+    if (SDL_X11_HAVE_XCURSOR) {
+        x11_cursor = X11_CreateXCursorCursor(surface, hot_x, hot_y);
+    }
 #endif
-        if (x11_cursor == None) {
-            x11_cursor = X11_CreatePixmapCursor(surface, hot_x, hot_y);
-        }
-        cursor->internal = (void *)(uintptr_t)x11_cursor;
+    if (x11_cursor == None) {
+        x11_cursor = X11_CreatePixmapCursor(surface, hot_x, hot_y);
     }
-
-    return cursor;
+    return X11_CreateCursorAndData(x11_cursor);
 }
 
 static unsigned int GetLegacySystemCursorShape(SDL_SystemCursor id)
@@ -262,10 +273,7 @@ static SDL_Cursor *X11_CreateSystemCursor(SDL_SystemCursor id)
     }
 
     if (x11_cursor != None) {
-        cursor = SDL_calloc(1, sizeof(*cursor));
-        if (cursor) {
-            cursor->internal = (void *)(uintptr_t)x11_cursor;
-        }
+        cursor = X11_CreateCursorAndData(x11_cursor);
     }
 
     return cursor;
@@ -273,11 +281,12 @@ static SDL_Cursor *X11_CreateSystemCursor(SDL_SystemCursor id)
 
 static void X11_FreeCursor(SDL_Cursor *cursor)
 {
-    Cursor x11_cursor = (Cursor)cursor->internal;
+    Cursor x11_cursor = cursor->internal->cursor;
 
     if (x11_cursor != None) {
         X11_XFreeCursor(GetDisplay(), x11_cursor);
     }
+    SDL_free(cursor->internal);
     SDL_free(cursor);
 }
 
@@ -286,7 +295,7 @@ static int X11_ShowCursor(SDL_Cursor *cursor)
     Cursor x11_cursor = 0;
 
     if (cursor) {
-        x11_cursor = (Cursor)cursor->internal;
+        x11_cursor = cursor->internal->cursor;
     } else {
         x11_cursor = X11_CreateEmptyCursor();
     }