Skip to content

Commit

Permalink
Sync SDL3 wiki -> header
Browse files Browse the repository at this point in the history
  • Loading branch information
SDLWikiBot committed Jul 19, 2024
1 parent a340de6 commit 975457c
Show file tree
Hide file tree
Showing 30 changed files with 426 additions and 250 deletions.
59 changes: 59 additions & 0 deletions docs/README-strings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# String policies in SDL3.

## Encoding.

Unless otherwise specified, all strings in SDL, across all platforms, are
UTF-8 encoded and can represent the full range of [Unicode](https://unicode.org).


## The SDL Get String Rule.

Did you see 'SDL_GetStringRule' in the wiki or headers? Here are the details
that aren't worth copying across dozens of functions' documentation.

tl;dr: If an SDL function returns a `const char *` string, do not modify or
free it, and if you need to save it, make a copy right away.

In several cases, SDL wants to return a string to the app, and the question
in any library that does this is: _who owns this thing?_

The answer in almost all cases, is that SDL does, but not for long.

The pointer is only guaranteed to be valid until the next time the event
queue is updated, or SDL_Quit is called.

The reason for this is memory safety.

There are several strings that SDL provides that could be freed at
any moment. For example, an app calls SDL_GetAudioDeviceName(), which returns
a string that is part of the internal audio device structure. But, while this
function is returning, the user yanks the USB audio device out of the
computer, and SDL decides to deallocate the structure...and the string!
Now the app is holding a pointer that didn't live long enough to be useful,
and could crash if accessed.

To avoid this, instead of calling SDL_free on a string as soon as it's done
with it, SDL adds the pointer to a list. This list is freed at specific
points: when the event queue is run (for ongoing cleanup) and when SDL_Quit
is called (to catch things that are just hanging around). This allows the
app to use a string without worrying about it becoming bogus in the middle
of a printf() call. If the app needs it for longer, it should copy it.

When does "the event queue run"? There are several points:

- If the app calls SDL_PumpEvents() _from any thread_.
- SDL_PumpEvents is also called by several other APIs internally:
SDL_PollEvent(), SDL_PeepEvents(), SDL_WaitEvent(),
SDL_WaitEventTimeout(), and maybe others.
- If you are using [the main callbacks](main-functions#main-callbacks-in-sdl3),
the event queue can run immediately after any of the callback functions
return.

Note that these are just guaranteed minimum lifespans; any given string
might live much longer--some might even be static memory that is _never_
deallocated--but this rule promises that the app has a safe window.

Note that none of this applies if the return value is `char *` instead of
`const char *`. Please see the specific function's documentation for how
to handle those pointers.

68 changes: 40 additions & 28 deletions include/SDL3/SDL_audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,8 @@ extern SDL_DECLSPEC int SDLCALL SDL_GetNumAudioDrivers(void);
* "coreaudio" or "wasapi". These never have Unicode characters, and are not
* meant to be proper names.
*
* This returns temporary memory which will be automatically freed later, and can be claimed with SDL_ClaimTemporaryMemory().
* This returns temporary memory which will be automatically freed later, and
* can be claimed with SDL_ClaimTemporaryMemory().
*
* \param index the index of the audio driver; the value ranges from 0 to
* SDL_GetNumAudioDrivers() - 1.
Expand All @@ -423,7 +424,8 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetAudioDriver(int index);
* "coreaudio" or "wasapi". These never have Unicode characters, and are not
* meant to be proper names.
*
* This returns temporary memory which will be automatically freed later, and can be claimed with SDL_ClaimTemporaryMemory().
* This returns temporary memory which will be automatically freed later, and
* can be claimed with SDL_ClaimTemporaryMemory().
*
* \returns the name of the current audio driver or NULL if no driver has been
* initialized.
Expand All @@ -448,11 +450,13 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetCurrentAudioDriver(void);
* If this function returns NULL, to signify an error, `*count` will be set to
* zero.
*
* This returns temporary memory which will be automatically freed later, and can be claimed with SDL_ClaimTemporaryMemory().
* This returns temporary memory which will be automatically freed later, and
* can be claimed with SDL_ClaimTemporaryMemory().
*
* \param count a pointer filled in with the number of devices returned, may be NULL.
* \returns a 0 terminated array of device instance IDs or NULL on error; call SDL_GetError() for more
* information.
* \param count a pointer filled in with the number of devices returned, may
* be NULL.
* \returns a 0 terminated array of device instance IDs or NULL on error; call
* SDL_GetError() for more information.
*
* \threadsafety It is safe to call this function from any thread.
*
Expand All @@ -477,11 +481,13 @@ extern SDL_DECLSPEC const SDL_AudioDeviceID * SDLCALL SDL_GetAudioPlaybackDevice
* If this function returns NULL, to signify an error, `*count` will be set to
* zero.
*
* This returns temporary memory which will be automatically freed later, and can be claimed with SDL_ClaimTemporaryMemory().
* This returns temporary memory which will be automatically freed later, and
* can be claimed with SDL_ClaimTemporaryMemory().
*
* \param count a pointer filled in with the number of devices returned, may be NULL.
* \returns a 0 terminated array of device instance IDs, or NULL on failure; call SDL_GetError() for more
* information.
* \param count a pointer filled in with the number of devices returned, may
* be NULL.
* \returns a 0 terminated array of device instance IDs, or NULL on failure;
* call SDL_GetError() for more information.
*
* \threadsafety It is safe to call this function from any thread.
*
Expand All @@ -495,7 +501,8 @@ extern SDL_DECLSPEC const SDL_AudioDeviceID * SDLCALL SDL_GetAudioRecordingDevic
/**
* Get the human-readable name of a specific audio device.
*
* This returns temporary memory which will be automatically freed later, and can be claimed with SDL_ClaimTemporaryMemory().
* This returns temporary memory which will be automatically freed later, and
* can be claimed with SDL_ClaimTemporaryMemory().
*
* \param devid the instance ID of the device to query.
* \returns the name of the audio device, or NULL on failure; call
Expand Down Expand Up @@ -555,7 +562,8 @@ extern SDL_DECLSPEC int SDLCALL SDL_GetAudioDeviceFormat(SDL_AudioDeviceID devid
* Audio devices usually have no remapping applied. This is represented by
* returning NULL, and does not signify an error.
*
* This returns temporary memory which will be automatically freed later, and can be claimed with SDL_ClaimTemporaryMemory().
* This returns temporary memory which will be automatically freed later, and
* can be claimed with SDL_ClaimTemporaryMemory().
*
* \param devid the instance ID of the device to query.
* \param count On output, set to number of channels in the map. Can be NULL.
Expand Down Expand Up @@ -634,8 +642,8 @@ extern SDL_DECLSPEC const int * SDLCALL SDL_GetAudioDeviceChannelMap(SDL_AudioDe
* default device.
* \param spec the requested device configuration. Can be NULL to use
* reasonable defaults.
* \returns the device ID on success or 0 on failure; call SDL_GetError() for more
* information.
* \returns the device ID on success or 0 on failure; call SDL_GetError() for
* more information.
*
* \threadsafety It is safe to call this function from any thread.
*
Expand Down Expand Up @@ -739,8 +747,8 @@ extern SDL_DECLSPEC SDL_bool SDLCALL SDL_AudioDevicePaused(SDL_AudioDeviceID dev
* this function will always return -1.0f when used on physical devices.
*
* \param devid the audio device to query.
* \returns the gain of the device or -1.0f on failure; call
* SDL_GetError() for more information.
* \returns the gain of the device or -1.0f on failure; call SDL_GetError()
* for more information.
*
* \threadsafety It is safe to call this function from any thread.
*
Expand Down Expand Up @@ -831,7 +839,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_CloseAudioDevice(SDL_AudioDeviceID devid);
* \param streams an array of audio streams to unbind.
* \param num_streams number streams listed in the `streams` array.
* \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information.
* SDL_GetError() for more information.
*
* \threadsafety It is safe to call this function from any thread.
*
Expand All @@ -851,8 +859,8 @@ extern SDL_DECLSPEC int SDLCALL SDL_BindAudioStreams(SDL_AudioDeviceID devid, SD
*
* \param devid an audio device to bind a stream to.
* \param stream an audio stream to bind to a device.
* \returns 0 on success or a negative error code on failure; call SDL_GetError() for more
* information.
* \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information.
*
* \threadsafety It is safe to call this function from any thread.
*
Expand Down Expand Up @@ -992,7 +1000,7 @@ extern SDL_DECLSPEC int SDLCALL SDL_GetAudioStreamFormat(SDL_AudioStream *stream
* \param dst_spec the new format of the audio output; if NULL, it is not
* changed.
* \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information.
* SDL_GetError() for more information.
*
* \threadsafety It is safe to call this function from any thread, as it holds
* a stream-specific mutex while running.
Expand Down Expand Up @@ -1059,8 +1067,8 @@ extern SDL_DECLSPEC int SDLCALL SDL_SetAudioStreamFrequencyRatio(SDL_AudioStream
* Audio streams default to a gain of 1.0f (no change in output).
*
* \param stream the SDL_AudioStream to query.
* \returns the gain of the stream or -1.0f on failure; call
* SDL_GetError() for more information.
* \returns the gain of the stream or -1.0f on failure; call SDL_GetError()
* for more information.
*
* \threadsafety It is safe to call this function from any thread, as it holds
* a stream-specific mutex while running.
Expand Down Expand Up @@ -1105,7 +1113,8 @@ extern SDL_DECLSPEC int SDLCALL SDL_SetAudioStreamGain(SDL_AudioStream *stream,
* Audio streams default to no remapping applied. This is represented by
* returning NULL, and does not signify an error.
*
* This returns temporary memory which will be automatically freed later, and can be claimed with SDL_ClaimTemporaryMemory().
* This returns temporary memory which will be automatically freed later, and
* can be claimed with SDL_ClaimTemporaryMemory().
*
* \param stream the SDL_AudioStream to query.
* \param count On output, set to number of channels in the map. Can be NULL.
Expand All @@ -1130,7 +1139,8 @@ extern SDL_DECLSPEC const int * SDLCALL SDL_GetAudioStreamInputChannelMap(SDL_Au
* Audio streams default to no remapping applied. This is represented by
* returning NULL, and does not signify an error.
*
* This returns temporary memory which will be automatically freed later, and can be claimed with SDL_ClaimTemporaryMemory().
* This returns temporary memory which will be automatically freed later, and
* can be claimed with SDL_ClaimTemporaryMemory().
*
* \param stream the SDL_AudioStream to query.
* \param count On output, set to number of channels in the map. Can be NULL.
Expand Down Expand Up @@ -1289,8 +1299,8 @@ extern SDL_DECLSPEC int SDLCALL SDL_PutAudioStreamData(SDL_AudioStream *stream,
* \param stream the stream the audio is being requested from.
* \param buf a buffer to fill with audio data.
* \param len the maximum number of bytes to fill.
* \returns the number of bytes read from the stream or a negative error code on failure; call
* SDL_GetError() for more information.
* \returns the number of bytes read from the stream or a negative error code
* on failure; call SDL_GetError() for more information.
*
* \threadsafety It is safe to call this function from any thread, but if the
* stream has a callback set, the caller might need to manage
Expand Down Expand Up @@ -1572,7 +1582,8 @@ typedef void (SDLCALL *SDL_AudioStreamCallback)(void *userdata, SDL_AudioStream
* \param userdata an opaque pointer provided to the callback for its own
* personal use.
* \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information. This only fails if `stream` is NULL.
* SDL_GetError() for more information. This only fails if `stream`
* is NULL.
*
* \threadsafety It is safe to call this function from any thread.
*
Expand Down Expand Up @@ -1621,7 +1632,8 @@ extern SDL_DECLSPEC int SDLCALL SDL_SetAudioStreamGetCallback(SDL_AudioStream *s
* \param userdata an opaque pointer provided to the callback for its own
* personal use.
* \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information. This only fails if `stream` is NULL.
* SDL_GetError() for more information. This only fails if `stream`
* is NULL.
*
* \threadsafety It is safe to call this function from any thread.
*
Expand Down
44 changes: 25 additions & 19 deletions include/SDL3/SDL_camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ extern SDL_DECLSPEC int SDLCALL SDL_GetNumCameraDrivers(void);
* "coremedia" or "android". These never have Unicode characters, and are not
* meant to be proper names.
*
* This returns temporary memory which will be automatically freed later, and can be claimed with SDL_ClaimTemporaryMemory().
* This returns temporary memory which will be automatically freed later, and
* can be claimed with SDL_ClaimTemporaryMemory().
*
* \param index the index of the camera driver; the value ranges from 0 to
* SDL_GetNumCameraDrivers() - 1.
Expand All @@ -156,7 +157,8 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetCameraDriver(int index);
* "coremedia" or "android". These never have Unicode characters, and are not
* meant to be proper names.
*
* This returns temporary memory which will be automatically freed later, and can be claimed with SDL_ClaimTemporaryMemory().
* This returns temporary memory which will be automatically freed later, and
* can be claimed with SDL_ClaimTemporaryMemory().
*
* \returns the name of the current camera driver or NULL if no driver has
* been initialized.
Expand All @@ -170,12 +172,13 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetCurrentCameraDriver(void);
/**
* Get a list of currently connected camera devices.
*
* This returns temporary memory which will be automatically freed later, and can be claimed with SDL_ClaimTemporaryMemory().
* This returns temporary memory which will be automatically freed later, and
* can be claimed with SDL_ClaimTemporaryMemory().
*
* \param count a pointer filled in with the number of cameras returned, may be
* NULL.
* \returns a 0 terminated array of camera instance IDs or NULL on failure; call SDL_GetError() for more
* information.
* \param count a pointer filled in with the number of cameras returned, may
* be NULL.
* \returns a 0 terminated array of camera instance IDs or NULL on failure;
* call SDL_GetError() for more information.
*
* \threadsafety It is safe to call this function from any thread.
*
Expand All @@ -201,18 +204,20 @@ extern SDL_DECLSPEC const SDL_CameraID * SDLCALL SDL_GetCameras(int *count);
* If `count` is not NULL, it will be filled with the number of elements in
* the returned array.
*
* Note that it's legal for a camera to supply an empty list. This is what will happen on
* Emscripten builds, since that platform won't tell _anything_ about
* available cameras until you've opened one, and won't even tell if there
* _is_ a camera until the user has given you permission to check through a
* scary warning popup.
* Note that it's legal for a camera to supply an empty list. This is what
* will happen on Emscripten builds, since that platform won't tell _anything_
* about available cameras until you've opened one, and won't even tell if
* there _is_ a camera until the user has given you permission to check
* through a scary warning popup.
*
* This returns temporary memory which will be automatically freed later, and can be claimed with SDL_ClaimTemporaryMemory().
* This returns temporary memory which will be automatically freed later, and
* can be claimed with SDL_ClaimTemporaryMemory().
*
* \param devid the camera device instance ID to query.
* \param count a pointer filled in with the number of elements in the list, may be NULL.
* \returns a NULL terminated array of pointers to SDL_CameraSpec or NULL on failure; call
* SDL_GetError() for more information.
* \param count a pointer filled in with the number of elements in the list,
* may be NULL.
* \returns a NULL terminated array of pointers to SDL_CameraSpec or NULL on
* failure; call SDL_GetError() for more information.
*
* \threadsafety It is safe to call this function from any thread.
*
Expand All @@ -226,7 +231,8 @@ extern SDL_DECLSPEC const SDL_CameraSpec * const * SDLCALL SDL_GetCameraSupporte
/**
* Get the human-readable device name for a camera.
*
* This returns temporary memory which will be automatically freed later, and can be claimed with SDL_ClaimTemporaryMemory().
* This returns temporary memory which will be automatically freed later, and
* can be claimed with SDL_ClaimTemporaryMemory().
*
* \param instance_id the camera device instance ID.
* \returns a human-readable device name or NULL on failure; call
Expand Down Expand Up @@ -293,8 +299,8 @@ extern SDL_DECLSPEC SDL_CameraPosition SDLCALL SDL_GetCameraPosition(SDL_CameraI
* \param instance_id the camera device instance ID.
* \param spec the desired format for data the device will provide. Can be
* NULL.
* \returns an SDL_Camera object or NULL on failure; call SDL_GetError() for more
* information.
* \returns an SDL_Camera object or NULL on failure; call SDL_GetError() for
* more information.
*
* \threadsafety It is safe to call this function from any thread.
*
Expand Down
9 changes: 6 additions & 3 deletions include/SDL3/SDL_clipboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ extern SDL_DECLSPEC int SDLCALL SDL_SetClipboardText(const char *text);
* This functions returns empty string if there was not enough memory left for
* a copy of the clipboard's content.
*
* This returns temporary memory which will be automatically freed later, and can be claimed with SDL_ClaimTemporaryMemory().
* This returns temporary memory which will be automatically freed later, and
* can be claimed with SDL_ClaimTemporaryMemory().
*
* \returns the clipboard text on success or an empty string on failure; call
* SDL_GetError() for more information.
Expand Down Expand Up @@ -106,7 +107,8 @@ extern SDL_DECLSPEC int SDLCALL SDL_SetPrimarySelectionText(const char *text);
* This functions returns empty string if there was not enough memory left for
* a copy of the primary selection's content.
*
* This returns temporary memory which will be automatically freed later, and can be claimed with SDL_ClaimTemporaryMemory().
* This returns temporary memory which will be automatically freed later, and
* can be claimed with SDL_ClaimTemporaryMemory().
*
* \returns the primary selection text on success or an empty string on
* failure; call SDL_GetError() for more information.
Expand Down Expand Up @@ -221,7 +223,8 @@ extern SDL_DECLSPEC int SDLCALL SDL_ClearClipboardData(void);
* \returns the retrieved data buffer or NULL on failure; call SDL_GetError()
* for more information.
*
* This returns temporary memory which will be automatically freed later, and can be claimed with SDL_ClaimTemporaryMemory().
* This returns temporary memory which will be automatically freed
* later, and can be claimed with SDL_ClaimTemporaryMemory().
*
* \since This function is available since SDL 3.0.0.
*
Expand Down
Loading

0 comments on commit 975457c

Please sign in to comment.