Merge commit 'cbd01874759dad39718e1496d241c4ae5eceaff1' into main
commit
ca18ab00a7
|
@ -30,6 +30,7 @@ General:
|
||||||
* Added joystick event SDL_JOYBATTERYUPDATED for when battery status changes.
|
* Added joystick event SDL_JOYBATTERYUPDATED for when battery status changes.
|
||||||
* Added SDL_GUIDToString() and SDL_GUIDFromString() to convert between SDL GUID and string
|
* Added SDL_GUIDToString() and SDL_GUIDFromString() to convert between SDL GUID and string
|
||||||
* Added SDL_HasLSX() and SDL_HasLASX() to detect LoongArch SIMD support
|
* Added SDL_HasLSX() and SDL_HasLASX() to detect LoongArch SIMD support
|
||||||
|
* Added SDL_GetOriginalMemoryFunctions()
|
||||||
|
|
||||||
Windows:
|
Windows:
|
||||||
* Added a D3D12 renderer implementation and SDL_RenderGetD3D12Device() to retrieve the D3D12 device associated with it
|
* Added a D3D12 renderer implementation and SDL_RenderGetD3D12Device() to retrieve the D3D12 device associated with it
|
||||||
|
|
|
@ -438,6 +438,16 @@ typedef void *(SDLCALL *SDL_calloc_func)(size_t nmemb, size_t size);
|
||||||
typedef void *(SDLCALL *SDL_realloc_func)(void *mem, size_t size);
|
typedef void *(SDLCALL *SDL_realloc_func)(void *mem, size_t size);
|
||||||
typedef void (SDLCALL *SDL_free_func)(void *mem);
|
typedef void (SDLCALL *SDL_free_func)(void *mem);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the original set of SDL memory functions
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 2.24.0.
|
||||||
|
*/
|
||||||
|
extern DECLSPEC void SDLCALL SDL_GetOriginalMemoryFunctions(SDL_malloc_func *malloc_func,
|
||||||
|
SDL_calloc_func *calloc_func,
|
||||||
|
SDL_realloc_func *realloc_func,
|
||||||
|
SDL_free_func *free_func);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current set of SDL memory functions
|
* Get the current set of SDL memory functions
|
||||||
*
|
*
|
||||||
|
|
|
@ -31,12 +31,22 @@ SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
|
||||||
/* Ignore call if invalid format pointer was passed */
|
/* Ignore call if invalid format pointer was passed */
|
||||||
if (fmt != NULL) {
|
if (fmt != NULL) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
int result;
|
||||||
SDL_error *error = SDL_GetErrBuf();
|
SDL_error *error = SDL_GetErrBuf();
|
||||||
|
|
||||||
error->error = 1; /* mark error as valid */
|
error->error = 1; /* mark error as valid */
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
SDL_vsnprintf(error->str, ERR_MAX_STRLEN, fmt, ap);
|
result = SDL_vsnprintf(error->str, error->len, fmt, ap);
|
||||||
|
if (result >= 0 && (size_t)result >= error->len && error->realloc_func) {
|
||||||
|
size_t len = (size_t)result + 1;
|
||||||
|
char *str = (char *)error->realloc_func(error->str, len);
|
||||||
|
if (str) {
|
||||||
|
error->str = str;
|
||||||
|
error->len = len;
|
||||||
|
SDL_vsnprintf(error->str, error->len, fmt, ap);
|
||||||
|
}
|
||||||
|
}
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
if (SDL_LogGetPriority(SDL_LOG_CATEGORY_ERROR) <= SDL_LOG_PRIORITY_DEBUG) {
|
if (SDL_LogGetPriority(SDL_LOG_CATEGORY_ERROR) <= SDL_LOG_PRIORITY_DEBUG) {
|
||||||
|
|
|
@ -27,12 +27,13 @@
|
||||||
#ifndef SDL_error_c_h_
|
#ifndef SDL_error_c_h_
|
||||||
#define SDL_error_c_h_
|
#define SDL_error_c_h_
|
||||||
|
|
||||||
#define ERR_MAX_STRLEN 128
|
|
||||||
|
|
||||||
typedef struct SDL_error
|
typedef struct SDL_error
|
||||||
{
|
{
|
||||||
int error; /* This is a numeric value corresponding to the current error */
|
int error; /* This is a numeric value corresponding to the current error */
|
||||||
char str[ERR_MAX_STRLEN];
|
char *str;
|
||||||
|
size_t len;
|
||||||
|
SDL_realloc_func realloc_func;
|
||||||
|
SDL_free_func free_func;
|
||||||
} SDL_error;
|
} SDL_error;
|
||||||
|
|
||||||
/* Defined in SDL_thread.c */
|
/* Defined in SDL_thread.c */
|
||||||
|
|
|
@ -851,3 +851,4 @@
|
||||||
++'_SDL_utf8strnlen'.'SDL2.dll'.'SDL_utf8strnlen'
|
++'_SDL_utf8strnlen'.'SDL2.dll'.'SDL_utf8strnlen'
|
||||||
# ++'_SDL_GDKGetTaskQueue'.'SDL2.dll'.'SDL_GDKGetTaskQueue'
|
# ++'_SDL_GDKGetTaskQueue'.'SDL2.dll'.'SDL_GDKGetTaskQueue'
|
||||||
# ++'_SDL_GDKRunApp'.'SDL2.dll'.'SDL_GDKRunApp'
|
# ++'_SDL_GDKRunApp'.'SDL2.dll'.'SDL_GDKRunApp'
|
||||||
|
++'_SDL_GetOriginalMemoryFunctions'.'SDL2.dll'.'SDL_GetOriginalMemoryFunctions'
|
||||||
|
|
|
@ -71,11 +71,25 @@ static void SDL_InitDynamicAPI(void);
|
||||||
|
|
||||||
#define SDL_DYNAPI_VARARGS(_static, name, initcall) \
|
#define SDL_DYNAPI_VARARGS(_static, name, initcall) \
|
||||||
_static int SDLCALL SDL_SetError##name(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) { \
|
_static int SDLCALL SDL_SetError##name(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) { \
|
||||||
char buf[512]; /* !!! FIXME: dynamic allocation */ \
|
char buf[128], *str = buf; \
|
||||||
|
int result; \
|
||||||
va_list ap; initcall; va_start(ap, fmt); \
|
va_list ap; initcall; va_start(ap, fmt); \
|
||||||
jump_table.SDL_vsnprintf(buf, sizeof (buf), fmt, ap); \
|
result = jump_table.SDL_vsnprintf(buf, sizeof(buf), fmt, ap); \
|
||||||
|
if (result >= 0 && (size_t)result >= sizeof(buf)) { \
|
||||||
|
size_t len = (size_t)result + 1; \
|
||||||
|
str = (char *)jump_table.SDL_malloc(len); \
|
||||||
|
if (str) { \
|
||||||
|
result = jump_table.SDL_vsnprintf(str, len, fmt, ap); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
va_end(ap); \
|
va_end(ap); \
|
||||||
return jump_table.SDL_SetError("%s", buf); \
|
if (result >= 0) { \
|
||||||
|
result = jump_table.SDL_SetError("%s", str); \
|
||||||
|
} \
|
||||||
|
if (str != buf) { \
|
||||||
|
jump_table.SDL_free(str); \
|
||||||
|
} \
|
||||||
|
return result; \
|
||||||
} \
|
} \
|
||||||
_static int SDLCALL SDL_sscanf##name(const char *buf, SDL_SCANF_FORMAT_STRING const char *fmt, ...) { \
|
_static int SDLCALL SDL_sscanf##name(const char *buf, SDL_SCANF_FORMAT_STRING const char *fmt, ...) { \
|
||||||
int retval; va_list ap; initcall; va_start(ap, fmt); \
|
int retval; va_list ap; initcall; va_start(ap, fmt); \
|
||||||
|
|
|
@ -877,3 +877,4 @@
|
||||||
#define SDL_utf8strnlen SDL_utf8strnlen_REAL
|
#define SDL_utf8strnlen SDL_utf8strnlen_REAL
|
||||||
#define SDL_GDKGetTaskQueue SDL_GDKGetTaskQueue_REAL
|
#define SDL_GDKGetTaskQueue SDL_GDKGetTaskQueue_REAL
|
||||||
#define SDL_GDKRunApp SDL_GDKRunApp_REAL
|
#define SDL_GDKRunApp SDL_GDKRunApp_REAL
|
||||||
|
#define SDL_GetOriginalMemoryFunctions SDL_GetOriginalMemoryFunctions_REAL
|
||||||
|
|
|
@ -960,3 +960,4 @@ SDL_DYNAPI_PROC(size_t,SDL_utf8strnlen,(const char *a, size_t b),(a,b),return)
|
||||||
SDL_DYNAPI_PROC(int,SDL_GDKGetTaskQueue,(XTaskQueueHandle *a),(a),return)
|
SDL_DYNAPI_PROC(int,SDL_GDKGetTaskQueue,(XTaskQueueHandle *a),(a),return)
|
||||||
SDL_DYNAPI_PROC(int,SDL_GDKRunApp,(SDL_main_func a, void *b),(a,b),return)
|
SDL_DYNAPI_PROC(int,SDL_GDKRunApp,(SDL_main_func a, void *b),(a,b),return)
|
||||||
#endif
|
#endif
|
||||||
|
SDL_DYNAPI_PROC(void,SDL_GetOriginalMemoryFunctions,(SDL_malloc_func *a, SDL_calloc_func *b, SDL_realloc_func *c, SDL_free_func *d),(a,b,c,d),)
|
||||||
|
|
|
@ -5328,6 +5328,25 @@ static struct
|
||||||
real_malloc, real_calloc, real_realloc, real_free, { 0 }
|
real_malloc, real_calloc, real_realloc, real_free, { 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void SDL_GetOriginalMemoryFunctions(SDL_malloc_func *malloc_func,
|
||||||
|
SDL_calloc_func *calloc_func,
|
||||||
|
SDL_realloc_func *realloc_func,
|
||||||
|
SDL_free_func *free_func)
|
||||||
|
{
|
||||||
|
if (malloc_func) {
|
||||||
|
*malloc_func = real_malloc;
|
||||||
|
}
|
||||||
|
if (calloc_func) {
|
||||||
|
*calloc_func = real_calloc;
|
||||||
|
}
|
||||||
|
if (realloc_func) {
|
||||||
|
*realloc_func = real_realloc;
|
||||||
|
}
|
||||||
|
if (free_func) {
|
||||||
|
*free_func = real_free;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SDL_GetMemoryFunctions(SDL_malloc_func *malloc_func,
|
void SDL_GetMemoryFunctions(SDL_malloc_func *malloc_func,
|
||||||
SDL_calloc_func *calloc_func,
|
SDL_calloc_func *calloc_func,
|
||||||
SDL_realloc_func *realloc_func,
|
SDL_realloc_func *realloc_func,
|
||||||
|
|
|
@ -200,19 +200,38 @@ SDL_Generic_SetTLSData(SDL_TLSData *storage)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Non-thread-safe global error variable */
|
||||||
|
static SDL_error *
|
||||||
|
SDL_GetStaticErrBuf()
|
||||||
|
{
|
||||||
|
static SDL_error SDL_global_error;
|
||||||
|
static char SDL_global_error_str[128];
|
||||||
|
SDL_global_error.str = SDL_global_error_str;
|
||||||
|
SDL_global_error.len = sizeof(SDL_global_error_str);
|
||||||
|
return &SDL_global_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
SDL_FreeErrBuf(void *data)
|
||||||
|
{
|
||||||
|
SDL_error *errbuf = (SDL_error *)data;
|
||||||
|
|
||||||
|
if (errbuf->str) {
|
||||||
|
errbuf->free_func(errbuf->str);
|
||||||
|
}
|
||||||
|
errbuf->free_func(errbuf);
|
||||||
|
}
|
||||||
|
|
||||||
/* Routine to get the thread-specific error variable */
|
/* Routine to get the thread-specific error variable */
|
||||||
SDL_error *
|
SDL_error *
|
||||||
SDL_GetErrBuf(void)
|
SDL_GetErrBuf(void)
|
||||||
{
|
{
|
||||||
#if SDL_THREADS_DISABLED
|
#if SDL_THREADS_DISABLED
|
||||||
/* Non-thread-safe global error variable */
|
return SDL_GetStaticErrBuf();
|
||||||
static SDL_error SDL_global_error;
|
|
||||||
return &SDL_global_error;
|
|
||||||
#else
|
#else
|
||||||
static SDL_SpinLock tls_lock;
|
static SDL_SpinLock tls_lock;
|
||||||
static SDL_bool tls_being_created;
|
static SDL_bool tls_being_created;
|
||||||
static SDL_TLSID tls_errbuf;
|
static SDL_TLSID tls_errbuf;
|
||||||
static SDL_error SDL_global_errbuf;
|
|
||||||
const SDL_error *ALLOCATION_IN_PROGRESS = (SDL_error *)-1;
|
const SDL_error *ALLOCATION_IN_PROGRESS = (SDL_error *)-1;
|
||||||
SDL_error *errbuf;
|
SDL_error *errbuf;
|
||||||
|
|
||||||
|
@ -233,24 +252,33 @@ SDL_GetErrBuf(void)
|
||||||
SDL_AtomicUnlock(&tls_lock);
|
SDL_AtomicUnlock(&tls_lock);
|
||||||
}
|
}
|
||||||
if (!tls_errbuf) {
|
if (!tls_errbuf) {
|
||||||
return &SDL_global_errbuf;
|
return SDL_GetStaticErrBuf();
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_MemoryBarrierAcquire();
|
SDL_MemoryBarrierAcquire();
|
||||||
errbuf = (SDL_error *)SDL_TLSGet(tls_errbuf);
|
errbuf = (SDL_error *)SDL_TLSGet(tls_errbuf);
|
||||||
if (errbuf == ALLOCATION_IN_PROGRESS) {
|
if (errbuf == ALLOCATION_IN_PROGRESS) {
|
||||||
return &SDL_global_errbuf;
|
return SDL_GetStaticErrBuf();
|
||||||
}
|
}
|
||||||
if (!errbuf) {
|
if (!errbuf) {
|
||||||
|
/* Get the original memory functions for this allocation because the lifetime
|
||||||
|
* of the error buffer may span calls to SDL_SetMemoryFunctions() by the app
|
||||||
|
*/
|
||||||
|
SDL_realloc_func realloc_func;
|
||||||
|
SDL_free_func free_func;
|
||||||
|
SDL_GetOriginalMemoryFunctions(NULL, NULL, &realloc_func, &free_func);
|
||||||
|
|
||||||
/* Mark that we're in the middle of allocating our buffer */
|
/* Mark that we're in the middle of allocating our buffer */
|
||||||
SDL_TLSSet(tls_errbuf, ALLOCATION_IN_PROGRESS, NULL);
|
SDL_TLSSet(tls_errbuf, ALLOCATION_IN_PROGRESS, NULL);
|
||||||
errbuf = (SDL_error *)SDL_malloc(sizeof(*errbuf));
|
errbuf = (SDL_error *)realloc_func(NULL, sizeof(*errbuf));
|
||||||
if (!errbuf) {
|
if (!errbuf) {
|
||||||
SDL_TLSSet(tls_errbuf, NULL, NULL);
|
SDL_TLSSet(tls_errbuf, NULL, NULL);
|
||||||
return &SDL_global_errbuf;
|
return SDL_GetStaticErrBuf();
|
||||||
}
|
}
|
||||||
SDL_zerop(errbuf);
|
SDL_zerop(errbuf);
|
||||||
SDL_TLSSet(tls_errbuf, errbuf, SDL_free);
|
errbuf->realloc_func = realloc_func;
|
||||||
|
errbuf->free_func = free_func;
|
||||||
|
SDL_TLSSet(tls_errbuf, errbuf, SDL_FreeErrBuf);
|
||||||
}
|
}
|
||||||
return errbuf;
|
return errbuf;
|
||||||
#endif /* SDL_THREADS_DISABLED */
|
#endif /* SDL_THREADS_DISABLED */
|
||||||
|
|
|
@ -125,6 +125,26 @@ static int main_testImpliedJoystickQuit (void *arg)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
main_testSetError(void *arg)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
char error[1024];
|
||||||
|
|
||||||
|
error[0] = '\0';
|
||||||
|
SDL_SetError("");
|
||||||
|
SDLTest_AssertCheck(SDL_strcmp(error, SDL_GetError()) == 0, "SDL_SetError(\"\")");
|
||||||
|
|
||||||
|
for (i = 0; i < (sizeof(error)-1); ++i) {
|
||||||
|
error[i] = 'a' + (i % 26);
|
||||||
|
}
|
||||||
|
error[i] = '\0';
|
||||||
|
SDL_SetError("%s", error);
|
||||||
|
SDLTest_AssertCheck(SDL_strcmp(error, SDL_GetError()) == 0, "SDL_SetError(\"abc...1023\")");
|
||||||
|
|
||||||
|
return TEST_COMPLETED;
|
||||||
|
}
|
||||||
|
|
||||||
static const SDLTest_TestCaseReference mainTest1 =
|
static const SDLTest_TestCaseReference mainTest1 =
|
||||||
{ (SDLTest_TestCaseFp)main_testInitQuitJoystickHaptic, "main_testInitQuitJoystickHaptic", "Tests SDL_Init/Quit of Joystick and Haptic subsystem", TEST_ENABLED};
|
{ (SDLTest_TestCaseFp)main_testInitQuitJoystickHaptic, "main_testInitQuitJoystickHaptic", "Tests SDL_Init/Quit of Joystick and Haptic subsystem", TEST_ENABLED};
|
||||||
|
|
||||||
|
@ -137,12 +157,16 @@ static const SDLTest_TestCaseReference mainTest3 =
|
||||||
static const SDLTest_TestCaseReference mainTest4 =
|
static const SDLTest_TestCaseReference mainTest4 =
|
||||||
{ (SDLTest_TestCaseFp)main_testImpliedJoystickQuit, "main_testImpliedJoystickQuit", "Tests that quit for gamecontroller doesn't quit joystick if you inited it explicitly", TEST_ENABLED};
|
{ (SDLTest_TestCaseFp)main_testImpliedJoystickQuit, "main_testImpliedJoystickQuit", "Tests that quit for gamecontroller doesn't quit joystick if you inited it explicitly", TEST_ENABLED};
|
||||||
|
|
||||||
|
static const SDLTest_TestCaseReference mainTest5 =
|
||||||
|
{ (SDLTest_TestCaseFp)main_testSetError, "main_testSetError", "Tests that SDL_SetError() handles arbitrarily large strings", TEST_ENABLED};
|
||||||
|
|
||||||
/* Sequence of Main test cases */
|
/* Sequence of Main test cases */
|
||||||
static const SDLTest_TestCaseReference *mainTests[] = {
|
static const SDLTest_TestCaseReference *mainTests[] = {
|
||||||
&mainTest1,
|
&mainTest1,
|
||||||
&mainTest2,
|
&mainTest2,
|
||||||
&mainTest3,
|
&mainTest3,
|
||||||
&mainTest4,
|
&mainTest4,
|
||||||
|
&mainTest5,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue