Selaa lähdekoodia

Try to create the dummy mouse cursor after video backend initialization

The mouse->CreateCursor function pointer will always be null if checked before the video backend is initialized, so a dummy default cursor with null internal structures was being created in all cases, not just for backends lacking cursor functionality. Move the check to after the video subsystem is initialized, when the function pointer check is valid.

Passing this dummy cursor with null internal structures to the Wayland backend would cause a crash, as it requires the internal cursor structures to be valid in order to store cursor backing data, even for default system cursors.
Frank Praznik 1 vuosi sitten
vanhempi
commit
2fff999a41
3 muutettua tiedostoa jossa 18 lisäystä ja 5 poistoa
  1. 10 2
      src/events/SDL_mouse.c
  2. 5 2
      src/events/SDL_mouse_c.h
  3. 3 1
      src/video/SDL_video.c

+ 10 - 2
src/events/SDL_mouse.c

@@ -162,7 +162,7 @@ static void SDLCALL SDL_MouseRelativeWarpMotionChanged(void *userdata, const cha
 }
 
 /* Public functions */
-int SDL_InitMouse(void)
+int SDL_PreInitMouse(void)
 {
     SDL_Mouse *mouse = SDL_GetMouse();
 
@@ -203,7 +203,16 @@ int SDL_InitMouse(void)
     mouse->was_touch_mouse_events = SDL_FALSE; /* no touch to mouse movement event pending */
 
     mouse->cursor_shown = SDL_TRUE;
+    return 0;
+}
 
+void SDL_PostInitMouse(void)
+{
+    SDL_Mouse *mouse = SDL_GetMouse();
+
+    /* 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) {
         SDL_Surface *surface = SDL_CreateSurface(1, 1, SDL_PIXELFORMAT_ARGB8888);
         if (surface) {
@@ -212,7 +221,6 @@ int SDL_InitMouse(void)
             SDL_DestroySurface(surface);
         }
     }
-    return 0;
 }
 
 void SDL_SetDefaultCursor(SDL_Cursor *cursor)

+ 5 - 2
src/events/SDL_mouse_c.h

@@ -122,8 +122,11 @@ typedef struct
     void *driverdata;
 } SDL_Mouse;
 
-/* Initialize the mouse subsystem */
-extern int SDL_InitMouse(void);
+/* Initialize the mouse subsystem, called before the main video driver is initialized */
+extern int SDL_PreInitMouse(void);
+
+/* Finish initializing the mouse subsystem, called after the main video driver was initialized */
+extern void SDL_PostInitMouse(void);
 
 /* Get the mouse state structure */
 SDL_Mouse *SDL_GetMouse(void);

+ 3 - 1
src/video/SDL_video.c

@@ -462,7 +462,7 @@ int SDL_VideoInit(const char *driver_name)
         goto pre_driver_error;
     }
     init_keyboard = SDL_TRUE;
-    if (SDL_InitMouse() < 0) {
+    if (SDL_PreInitMouse() < 0) {
         goto pre_driver_error;
     }
     init_mouse = SDL_TRUE;
@@ -558,6 +558,8 @@ int SDL_VideoInit(const char *driver_name)
         SDL_StartTextInput();
     }
 
+    SDL_PostInitMouse();
+
     /* We're ready to go! */
     return 0;