Browse Source

gamepad: Several gamepad mapping functions now follow the SDL_GetStringRule.

Reference Issue #10229.
Ryan C. Gordon 9 months ago
parent
commit
4dda785c69

+ 11 - 12
include/SDL3/SDL_gamepad.h

@@ -389,22 +389,20 @@ extern SDL_DECLSPEC int SDLCALL SDL_ReloadGamepadMappings(void);
 /**
  * Get the current gamepad mappings.
  *
- * You must free the returned pointer with SDL_free() when you are done with
- * it, but you do _not_ free each string in the array.
+ * The returned pointer follows the SDL_GetStringRule.
  *
  * \param count a pointer filled in with the number of mappings returned, can
  *              be NULL.
- * \returns an array of the mapping strings, NULL-terminated. Must be freed
- *          with SDL_free(). Returns NULL on error.
+ * \returns an array of the mapping strings, NULL-terminated. Returns NULL on error.
  *
  * \since This function is available since SDL 3.0.0.
  */
-extern SDL_DECLSPEC char ** SDLCALL SDL_GetGamepadMappings(int *count);
+extern SDL_DECLSPEC const char * const * SDLCALL SDL_GetGamepadMappings(int *count);
 
 /**
  * Get the gamepad mapping string for a given GUID.
  *
- * The returned string must be freed with SDL_free().
+ * The returned string follows the SDL_GetStringRule.
  *
  * \param guid a structure containing the GUID for which a mapping is desired.
  * \returns a mapping string or NULL on error; call SDL_GetError() for more
@@ -415,12 +413,12 @@ extern SDL_DECLSPEC char ** SDLCALL SDL_GetGamepadMappings(int *count);
  * \sa SDL_GetJoystickGUIDForID
  * \sa SDL_GetJoystickGUID
  */
-extern SDL_DECLSPEC char * SDLCALL SDL_GetGamepadMappingForGUID(SDL_JoystickGUID guid);
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetGamepadMappingForGUID(SDL_JoystickGUID guid);
 
 /**
  * Get the current mapping of a gamepad.
  *
- * The returned string must be freed with SDL_free().
+ * The returned string follows the SDL_GetStringRule.
  *
  * Details about mappings are discussed with SDL_AddGamepadMapping().
  *
@@ -435,7 +433,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_GetGamepadMappingForGUID(SDL_JoystickGUID
  * \sa SDL_GetGamepadMappingForGUID
  * \sa SDL_SetGamepadMapping
  */
-extern SDL_DECLSPEC char * SDLCALL SDL_GetGamepadMapping(SDL_Gamepad *gamepad);
+extern SDL_DECLSPEC const char * SDLCALL SDL_GetGamepadMapping(SDL_Gamepad *gamepad);
 
 /**
  * Set the current mapping of a joystick or gamepad.
@@ -651,16 +649,17 @@ extern SDL_DECLSPEC SDL_GamepadType SDLCALL SDL_GetRealGamepadTypeForID(SDL_Joys
  *
  * This can be called before any gamepads are opened.
  *
+ * The returned string follows the SDL_GetStringRule.
+ *
  * \param instance_id the joystick instance ID.
- * \returns the mapping string. Must be freed with SDL_free(). Returns NULL if
- *          no mapping is available.
+ * \returns the mapping string. Returns NULL if no mapping is available.
  *
  * \since This function is available since SDL 3.0.0.
  *
  * \sa SDL_GetGamepads
  * \sa SDL_GetGamepadMapping
  */
-extern SDL_DECLSPEC char *SDLCALL SDL_GetGamepadMappingForID(SDL_JoystickID instance_id);
+extern SDL_DECLSPEC const char *SDLCALL SDL_GetGamepadMappingForID(SDL_JoystickID instance_id);
 
 /**
  * Open a gamepad for use.

+ 4 - 4
src/dynapi/SDL_dynapi_procs.h

@@ -286,10 +286,10 @@ SDL_DYNAPI_PROC(SDL_Gamepad*,SDL_GetGamepadFromPlayerIndex,(int a),(a),return)
 SDL_DYNAPI_PROC(SDL_JoystickGUID,SDL_GetGamepadGUIDForID,(SDL_JoystickID a),(a),return)
 SDL_DYNAPI_PROC(SDL_JoystickID,SDL_GetGamepadID,(SDL_Gamepad *a),(a),return)
 SDL_DYNAPI_PROC(SDL_Joystick*,SDL_GetGamepadJoystick,(SDL_Gamepad *a),(a),return)
-SDL_DYNAPI_PROC(char*,SDL_GetGamepadMapping,(SDL_Gamepad *a),(a),return)
-SDL_DYNAPI_PROC(char*,SDL_GetGamepadMappingForGUID,(SDL_JoystickGUID a),(a),return)
-SDL_DYNAPI_PROC(char*,SDL_GetGamepadMappingForID,(SDL_JoystickID a),(a),return)
-SDL_DYNAPI_PROC(char**,SDL_GetGamepadMappings,(int *a),(a),return)
+SDL_DYNAPI_PROC(const char*,SDL_GetGamepadMapping,(SDL_Gamepad *a),(a),return)
+SDL_DYNAPI_PROC(const char*,SDL_GetGamepadMappingForGUID,(SDL_JoystickGUID a),(a),return)
+SDL_DYNAPI_PROC(const char*,SDL_GetGamepadMappingForID,(SDL_JoystickID a),(a),return)
+SDL_DYNAPI_PROC(const char * const *,SDL_GetGamepadMappings,(int *a),(a),return)
 SDL_DYNAPI_PROC(const char*,SDL_GetGamepadName,(SDL_Gamepad *a),(a),return)
 SDL_DYNAPI_PROC(const char*,SDL_GetGamepadNameForID,(SDL_JoystickID a),(a),return)
 SDL_DYNAPI_PROC(const char*,SDL_GetGamepadPath,(SDL_Gamepad *a),(a),return)

+ 10 - 5
src/joystick/SDL_gamepad.c

@@ -2125,7 +2125,7 @@ static char *CreateMappingString(GamepadMapping_t *mapping, SDL_JoystickGUID gui
     return pMappingString;
 }
 
-char **SDL_GetGamepadMappings(int *count)
+const char * const *SDL_GetGamepadMappings(int *count)
 {
     int num_mappings = 0;
     char **retval = NULL;
@@ -2198,13 +2198,14 @@ char **SDL_GetGamepadMappings(int *count)
         SDL_free(mappings);
     }
 
-    return retval;
+    SDL_FreeLater(retval);
+    return (const char * const *) retval;
 }
 
 /*
  * Get the mapping string for this GUID
  */
-char *SDL_GetGamepadMappingForGUID(SDL_JoystickGUID guid)
+const char *SDL_GetGamepadMappingForGUID(SDL_JoystickGUID guid)
 {
     char *retval;
 
@@ -2220,13 +2221,14 @@ char *SDL_GetGamepadMappingForGUID(SDL_JoystickGUID guid)
     }
     SDL_UnlockJoysticks();
 
+    SDL_FreeLater(retval);
     return retval;
 }
 
 /*
  * Get the mapping string for this device
  */
-char *SDL_GetGamepadMapping(SDL_Gamepad *gamepad)
+const char *SDL_GetGamepadMapping(SDL_Gamepad *gamepad)
 {
     char *retval;
 
@@ -2238,6 +2240,7 @@ char *SDL_GetGamepadMapping(SDL_Gamepad *gamepad)
     }
     SDL_UnlockJoysticks();
 
+    SDL_FreeLater(retval);
     return retval;
 }
 
@@ -2519,7 +2522,7 @@ SDL_GamepadType SDL_GetRealGamepadTypeForID(SDL_JoystickID instance_id)
     return type;
 }
 
-char *SDL_GetGamepadMappingForID(SDL_JoystickID instance_id)
+const char *SDL_GetGamepadMappingForID(SDL_JoystickID instance_id)
 {
     char *retval = NULL;
 
@@ -2534,6 +2537,8 @@ char *SDL_GetGamepadMappingForID(SDL_JoystickID instance_id)
         }
     }
     SDL_UnlockJoysticks();
+
+    SDL_FreeLater(retval);
     return retval;
 }
 

+ 5 - 8
test/gamepadutils.c

@@ -416,13 +416,12 @@ void UpdateGamepadImageFromGamepad(GamepadImage *ctx, SDL_Gamepad *gamepad)
     }
 
     ctx->type = SDL_GetGamepadType(gamepad);
-    char *mapping = SDL_GetGamepadMapping(gamepad);
+    const char *mapping = SDL_GetGamepadMapping(gamepad);
     if (mapping) {
         if (SDL_strstr(mapping, "SDL_GAMECONTROLLER_USE_BUTTON_LABELS")) {
             /* Just for display purposes */
             ctx->type = SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO;
         }
-        SDL_free(mapping);
     }
 
     for (i = 0; i < SDL_GAMEPAD_BUTTON_TOUCHPAD; ++i) {
@@ -750,7 +749,7 @@ void SetGamepadDisplayArea(GamepadDisplay *ctx, const SDL_FRect *area)
     SDL_copyp(&ctx->area, area);
 }
 
-static SDL_bool GetBindingString(const char *label, char *mapping, char *text, size_t size)
+static SDL_bool GetBindingString(const char *label, const char *mapping, char *text, size_t size)
 {
     char *key;
     char *value, *end;
@@ -791,7 +790,7 @@ static SDL_bool GetBindingString(const char *label, char *mapping, char *text, s
     return found;
 }
 
-static SDL_bool GetButtonBindingString(SDL_GamepadButton button, char *mapping, char *text, size_t size)
+static SDL_bool GetButtonBindingString(SDL_GamepadButton button, const char *mapping, char *text, size_t size)
 {
     char label[32];
     SDL_bool baxy_mapping = SDL_FALSE;
@@ -839,7 +838,7 @@ static SDL_bool GetButtonBindingString(SDL_GamepadButton button, char *mapping,
     }
 }
 
-static SDL_bool GetAxisBindingString(SDL_GamepadAxis axis, int direction, char *mapping, char *text, size_t size)
+static SDL_bool GetAxisBindingString(SDL_GamepadAxis axis, int direction, const char *mapping, char *text, size_t size)
 {
     char label[32];
 
@@ -1022,7 +1021,7 @@ void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad)
     const float arrow_extent = 48.0f;
     SDL_FRect dst, rect, highlight;
     Uint8 r, g, b, a;
-    char *mapping = NULL;
+    const char *mapping = NULL;
     SDL_bool has_accel;
     SDL_bool has_gyro;
 
@@ -1286,8 +1285,6 @@ void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad)
             }
         }
     }
-
-    SDL_free(mapping);
 }
 
 void DestroyGamepadDisplay(GamepadDisplay *ctx)

+ 5 - 5
test/testcontroller.c

@@ -973,6 +973,7 @@ static void DelController(SDL_JoystickID id)
 
 static void HandleGamepadRemapped(SDL_JoystickID id)
 {
+    const char *sdlmapping;
     char *mapping;
     int i = FindController(id);
 
@@ -987,7 +988,8 @@ static void HandleGamepadRemapped(SDL_JoystickID id)
     }
 
     /* Get the current mapping */
-    mapping = SDL_GetGamepadMapping(controllers[i].gamepad);
+    sdlmapping = SDL_GetGamepadMapping(controllers[i].gamepad);
+    mapping = sdlmapping ? SDL_strdup(sdlmapping) : NULL;
 
     /* Make sure the mapping has a valid name */
     if (mapping && !MappingHasName(mapping)) {
@@ -1063,10 +1065,9 @@ static void HandleGamepadAdded(SDL_JoystickID id, SDL_bool verbose)
         }
 
         if (verbose) {
-            char *mapping = SDL_GetGamepadMapping(gamepad);
+            const char *mapping = SDL_GetGamepadMapping(gamepad);
             if (mapping) {
                 SDL_Log("Mapping: %s\n", mapping);
-                SDL_free(mapping);
             }
         }
     } else {
@@ -2053,14 +2054,13 @@ int main(int argc, char *argv[])
 
     if (show_mappings) {
         int count = 0;
-        char **mappings = SDL_GetGamepadMappings(&count);
+        const char * const *mappings = SDL_GetGamepadMappings(&count);
         int map_i;
         SDL_Log("Supported mappings:\n");
         for (map_i = 0; map_i < count; ++map_i) {
             SDL_Log("\t%s\n", mappings[map_i]);
         }
         SDL_Log("\n");
-        SDL_free(mappings);
     }
 
     /* Create a window to display gamepad state */