From be67f0de1066fe4b0c9feed841ccd6193ceecc88 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Thu, 10 Aug 2023 11:40:36 -0700
Subject: [PATCH] Fixed crashes related to the default cursor on WinRT and
KMSDRM
Fixes https://github.com/libsdl-org/SDL/issues/8104
---
src/events/SDL_mouse.c | 55 ++++++++++++++++++++++------------------
src/events/SDL_mouse_c.h | 4 +--
2 files changed, 33 insertions(+), 26 deletions(-)
diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c
index a878405fa0dd..f5e0ed2e6a95 100644
--- a/src/events/SDL_mouse.c
+++ b/src/events/SDL_mouse.c
@@ -213,7 +213,7 @@ void SDL_PostInitMouse(void)
/* Create a dummy mouse cursor for video backends that don't support true cursors,
* so that mouse grab and focus functionality will work.
*/
- if (!mouse->CreateCursor) {
+ if (!mouse->default_cursor) {
SDL_Surface *surface = SDL_CreateSurface(1, 1, SDL_PIXELFORMAT_ARGB8888);
if (surface) {
SDL_memset(surface->pixels, 0, (size_t)surface->h * surface->pitch);
@@ -227,8 +227,20 @@ void SDL_SetDefaultCursor(SDL_Cursor *cursor)
{
SDL_Mouse *mouse = SDL_GetMouse();
- mouse->def_cursor = cursor;
- if (!mouse->cur_cursor) {
+ if (cursor == mouse->default_cursor) {
+ return;
+ }
+
+ if (mouse->default_cursor) {
+ SDL_Cursor *default_cursor = mouse->default_cursor;
+
+ mouse->default_cursor = NULL;
+ SDL_DestroyCursor(default_cursor);
+ }
+
+ mouse->default_cursor = cursor;
+
+ if (!mouse->current_cursor) {
SDL_SetCursor(cursor);
}
}
@@ -609,8 +621,8 @@ static int SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_
/* Move the mouse cursor, if needed */
if (mouse->cursor_shown && !mouse->relative_mode &&
- mouse->MoveCursor && mouse->cur_cursor) {
- mouse->MoveCursor(mouse->cur_cursor);
+ mouse->MoveCursor && mouse->current_cursor) {
+ mouse->MoveCursor(mouse->current_cursor);
}
/* Post the event, if desired */
@@ -860,15 +872,10 @@ void SDL_QuitMouse(void)
cursor = next;
}
mouse->cursors = NULL;
- mouse->cur_cursor = NULL;
+ mouse->current_cursor = NULL;
- if (mouse->def_cursor) {
- if (mouse->FreeCursor) {
- mouse->FreeCursor(mouse->def_cursor);
- } else {
- SDL_free(mouse->def_cursor);
- }
- mouse->def_cursor = NULL;
+ if (mouse->default_cursor) {
+ SDL_SetDefaultCursor(NULL);
}
if (mouse->sources) {
@@ -1301,14 +1308,14 @@ int SDL_SetCursor(SDL_Cursor *cursor)
SDL_Mouse *mouse = SDL_GetMouse();
/* Return immediately if setting the cursor to the currently set one (fixes #7151) */
- if (cursor == mouse->cur_cursor) {
+ if (cursor == mouse->current_cursor) {
return 0;
}
/* Set the new cursor */
if (cursor) {
/* Make sure the cursor is still valid for this mouse */
- if (cursor != mouse->def_cursor) {
+ if (cursor != mouse->default_cursor) {
SDL_Cursor *found;
for (found = mouse->cursors; found; found = found->next) {
if (found == cursor) {
@@ -1319,12 +1326,12 @@ int SDL_SetCursor(SDL_Cursor *cursor)
return SDL_SetError("Cursor not associated with the current mouse");
}
}
- mouse->cur_cursor = cursor;
+ mouse->current_cursor = cursor;
} else {
if (mouse->focus) {
- cursor = mouse->cur_cursor;
+ cursor = mouse->current_cursor;
} else {
- cursor = mouse->def_cursor;
+ cursor = mouse->default_cursor;
}
}
@@ -1347,7 +1354,7 @@ SDL_Cursor *SDL_GetCursor(void)
if (mouse == NULL) {
return NULL;
}
- return mouse->cur_cursor;
+ return mouse->current_cursor;
}
SDL_Cursor *SDL_GetDefaultCursor(void)
@@ -1357,7 +1364,7 @@ SDL_Cursor *SDL_GetDefaultCursor(void)
if (mouse == NULL) {
return NULL;
}
- return mouse->def_cursor;
+ return mouse->default_cursor;
}
void SDL_DestroyCursor(SDL_Cursor *cursor)
@@ -1369,11 +1376,11 @@ void SDL_DestroyCursor(SDL_Cursor *cursor)
return;
}
- if (cursor == mouse->def_cursor) {
+ if (cursor == mouse->default_cursor) {
return;
}
- if (cursor == mouse->cur_cursor) {
- SDL_SetCursor(mouse->def_cursor);
+ if (cursor == mouse->current_cursor) {
+ SDL_SetCursor(mouse->default_cursor);
}
for (prev = NULL, curr = mouse->cursors; curr;
@@ -1385,7 +1392,7 @@ void SDL_DestroyCursor(SDL_Cursor *cursor)
mouse->cursors = curr->next;
}
- if (mouse->FreeCursor) {
+ if (mouse->FreeCursor && curr->driverdata) {
mouse->FreeCursor(curr);
} else {
SDL_free(curr);
diff --git a/src/events/SDL_mouse_c.h b/src/events/SDL_mouse_c.h
index 0887b5626b13..3ff20d018dbb 100644
--- a/src/events/SDL_mouse_c.h
+++ b/src/events/SDL_mouse_c.h
@@ -114,8 +114,8 @@ typedef struct
SDL_MouseClickState *clickstate;
SDL_Cursor *cursors;
- SDL_Cursor *def_cursor;
- SDL_Cursor *cur_cursor;
+ SDL_Cursor *default_cursor;
+ SDL_Cursor *current_cursor;
SDL_bool cursor_shown;
/* Driver-dependent data. */