diff --git a/include/SDL3/SDL_properties.h b/include/SDL3/SDL_properties.h index 17b280ae1..655a21d41 100644 --- a/include/SDL3/SDL_properties.h +++ b/include/SDL3/SDL_properties.h @@ -39,6 +39,18 @@ extern "C" { */ typedef Uint32 SDL_PropertiesID; +/** + * SDL property type + */ +typedef enum +{ + SDL_PROPERTY_TYPE_INVALID, + SDL_PROPERTY_TYPE_POINTER, + SDL_PROPERTY_TYPE_STRING, + SDL_PROPERTY_TYPE_NUMBER, + SDL_PROPERTY_TYPE_FLOAT, +} SDL_PropertyType; + /** * Get the global SDL properties * @@ -105,24 +117,6 @@ extern DECLSPEC int SDLCALL SDL_LockProperties(SDL_PropertiesID props); */ extern DECLSPEC void SDLCALL SDL_UnlockProperties(SDL_PropertiesID props); -/** - * Set a property on a set of properties - * - * \param props the properties to modify - * \param name the name of the property to modify - * \param value the new value of the property, or NULL to delete the property - * \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. - * - * \since This function is available since SDL 3.0.0. - * - * \sa SDL_GetProperty - * \sa SDL_SetPropertyWithCleanup - */ -extern DECLSPEC int SDLCALL SDL_SetProperty(SDL_PropertiesID props, const char *name, void *value); - /** * Set a property on a set of properties with a cleanup function that is * called when the property is deleted @@ -145,6 +139,88 @@ extern DECLSPEC int SDLCALL SDL_SetProperty(SDL_PropertiesID props, const char * */ extern DECLSPEC int SDLCALL SDL_SetPropertyWithCleanup(SDL_PropertiesID props, const char *name, void *value, void (SDLCALL *cleanup)(void *userdata, void *value), void *userdata); +/** + * Set a property on a set of properties + * + * \param props the properties to modify + * \param name the name of the property to modify + * \param value the new value of the property, or NULL to delete the property + * \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. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_GetProperty + * \sa SDL_SetPropertyWithCleanup + */ +extern DECLSPEC int SDLCALL SDL_SetProperty(SDL_PropertiesID props, const char *name, void *value); + +/** + * Set a string property on a set of properties + * + * \param props the properties to modify + * \param name the name of the property to modify + * \param value the new value of the property, or NULL to delete the property + * \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. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_GetStringProperty + */ +extern DECLSPEC int SDLCALL SDL_SetStringProperty(SDL_PropertiesID props, const char *name, const char *value); + +/** + * Set an integer property on a set of properties + * + * \param props the properties to modify + * \param name the name of the property to modify + * \param value the new value of the property + * \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. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_GetNumberProperty + */ +extern DECLSPEC int SDLCALL SDL_SetNumberProperty(SDL_PropertiesID props, const char *name, Sint64 value); + +/** + * Set a floating point property on a set of properties + * + * \param props the properties to modify + * \param name the name of the property to modify + * \param value the new value of the property + * \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. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_GetFloatProperty + */ +extern DECLSPEC int SDLCALL SDL_SetFloatProperty(SDL_PropertiesID props, const char *name, float value); + +/** + * Get the type of a property on a set of properties + * + * \param props the properties to query + * \param name the name of the property to query + * \returns the type of the property, or SDL_PROPERTY_TYPE_INVALID if it is not set. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + */ +extern DECLSPEC SDL_PropertyType SDLCALL SDL_GetPropertyType(SDL_PropertiesID props, const char *name); + /** * Get a property on a set of properties * @@ -155,7 +231,8 @@ extern DECLSPEC int SDLCALL SDL_SetPropertyWithCleanup(SDL_PropertiesID props, c * * \param props the properties to query * \param name the name of the property to query - * \returns the value of the property, or NULL if it is not set. + * \param default_value the default value of the property + * \returns the value of the property, or `default_value` if it is not set or not a pointer property. * * \threadsafety It is safe to call this function from any thread, although * the data returned is not protected and could potentially be @@ -165,9 +242,65 @@ extern DECLSPEC int SDLCALL SDL_SetPropertyWithCleanup(SDL_PropertiesID props, c * * \since This function is available since SDL 3.0.0. * + * \sa SDL_GetPropertyType * \sa SDL_SetProperty */ -extern DECLSPEC void *SDLCALL SDL_GetProperty(SDL_PropertiesID props, const char *name); +extern DECLSPEC void *SDLCALL SDL_GetProperty(SDL_PropertiesID props, const char *name, void *default_value); + +/** + * Get a string property on a set of properties + * + * \param props the properties to query + * \param name the name of the property to query + * \param default_value the default value of the property + * \returns the value of the property, or `default_value` if it is not set or not a string property. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_GetPropertyType + * \sa SDL_SetStringProperty + */ +extern DECLSPEC const char *SDLCALL SDL_GetStringProperty(SDL_PropertiesID props, const char *name, const char *default_value); + +/** + * Get a number property on a set of properties + * + * You can use SDL_GetPropertyType() to query whether the property exists and is a number property. + * + * \param props the properties to query + * \param name the name of the property to query + * \param default_value the default value of the property + * \returns the value of the property, or `default_value` if it is not set or not a number property. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_GetPropertyType + * \sa SDL_SetNumberProperty + */ +extern DECLSPEC Sint64 SDLCALL SDL_GetNumberProperty(SDL_PropertiesID props, const char *name, Sint64 default_value); + +/** + * Get a floating point property on a set of properties + * + * You can use SDL_GetPropertyType() to query whether the property exists and is a floating point property. + * + * \param props the properties to query + * \param name the name of the property to query + * \param default_value the default value of the property + * \returns the value of the property, or `default_value` if it is not set or not a float property. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_GetPropertyType + * \sa SDL_SetFloatProperty + */ +extern DECLSPEC float SDLCALL SDL_GetFloatProperty(SDL_PropertiesID props, const char *name, float default_value); /** * Clear a property on a set of properties @@ -185,6 +318,24 @@ extern DECLSPEC void *SDLCALL SDL_GetProperty(SDL_PropertiesID props, const char */ extern DECLSPEC int SDLCALL SDL_ClearProperty(SDL_PropertiesID props, const char *name); +typedef void (SDLCALL *SDL_EnumeratePropertiesCallback)(void *userdata, SDL_PropertiesID props, const char *name); +/** + * Enumerate the properties on a set of properties + * + * The callback function is called for each property on the set of properties. The properties are locked during enumeration. + * + * \param props the properties to query + * \param callback the function to call for each property + * \param userdata a pointer that is passed to `callback` + * \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. + * + * \since This function is available since SDL 3.0.0. + */ +extern DECLSPEC int SDLCALL SDL_EnumerateProperties(SDL_PropertiesID props, SDL_EnumeratePropertiesCallback callback, void *userdata); + /** * Destroy a set of properties * diff --git a/include/SDL3/SDL_render.h b/include/SDL3/SDL_render.h index 120543dd4..72cb5d263 100644 --- a/include/SDL3/SDL_render.h +++ b/include/SDL3/SDL_render.h @@ -311,10 +311,10 @@ extern DECLSPEC int SDLCALL SDL_GetRendererInfo(SDL_Renderer *renderer, SDL_Rend * * The following properties are provided by SDL: * ``` - * "SDL.renderer.d3d9.device" - the IDirect3DDevice9 associated with the renderer - * "SDL.renderer.d3d11.device" - the ID3D11Device associated with the renderer - * "SDL.renderer.d3d12.device" - the ID3D12Device associated with the renderer - * "SDL.renderer.d3d12.command_queue" - the ID3D12CommandQueue associated with the renderer + * "SDL.renderer.d3d9.device" (pointer) - the IDirect3DDevice9 associated with the renderer + * "SDL.renderer.d3d11.device" (pointer) - the ID3D11Device associated with the renderer + * "SDL.renderer.d3d12.device" (pointer) - the ID3D12Device associated with the renderer + * "SDL.renderer.d3d12.command_queue" (pointer) - the ID3D12CommandQueue associated with the renderer * ``` * * \param renderer the rendering context @@ -424,33 +424,33 @@ extern DECLSPEC SDL_Texture *SDLCALL SDL_CreateTextureFromSurface(SDL_Renderer * * * With the direct3d11 renderer: * ``` - * "SDL.texture.d3d11.texture" - the ID3D11Texture2D associated with the texture - * "SDL.texture.d3d11.texture_u" - the ID3D11Texture2D associated with the U plane of a YUV texture - * "SDL.texture.d3d11.texture_v" - the ID3D11Texture2D associated with the V plane of a YUV texture + * "SDL.texture.d3d11.texture" (pointer) - the ID3D11Texture2D associated with the texture + * "SDL.texture.d3d11.texture_u" (pointer) - the ID3D11Texture2D associated with the U plane of a YUV texture + * "SDL.texture.d3d11.texture_v" (pointer) - the ID3D11Texture2D associated with the V plane of a YUV texture * ``` * * With the direct3d12 renderer: * ``` - * "SDL.texture.d3d12.texture" - the ID3D12Resource associated with the texture - * "SDL.texture.d3d12.texture_u" - the ID3D12Resource associated with the U plane of a YUV texture - * "SDL.texture.d3d12.texture_v" - the ID3D12Resource associated with the V plane of a YUV texture + * "SDL.texture.d3d12.texture" (pointer) - the ID3D12Resource associated with the texture + * "SDL.texture.d3d12.texture_u" (pointer) - the ID3D12Resource associated with the U plane of a YUV texture + * "SDL.texture.d3d12.texture_v" (pointer) - the ID3D12Resource associated with the V plane of a YUV texture * ``` * * With the opengl renderer: * ``` - * "SDL.texture.opengl.texture" - the GLuint texture associated with the texture - * "SDL.texture.opengl.texture_u" - the GLuint texture associated with the U plane of a YUV texture - * "SDL.texture.opengl.texture_v" - the GLuint texture associated with the V plane of a YUV texture - * "SDL.texture.opengl.tex_w" - the 16.16 fixed point texture coordinate width of the texture - * "SDL.texture.opengl.tex_h" - the 16.16 fixed point texture coordinate height of the texture + * "SDL.texture.opengl.texture" (number) - the GLuint texture associated with the texture + * "SDL.texture.opengl.texture_u" (number) - the GLuint texture associated with the U plane of a YUV texture + * "SDL.texture.opengl.texture_v" (number) - the GLuint texture associated with the V plane of a YUV texture + * "SDL.texture.opengl.tex_w" (float) - the texture coordinate width of the texture (0.0 - 1.0) + * "SDL.texture.opengl.tex_h" (float) - the texture coordinate height of the texture (0.0 - 1.0) * ``` * * With the opengles2 renderer: * ``` - * "SDL.texture.opengles2.texture" - the GLuint texture associated with the texture - * "SDL.texture.opengles2.texture_uv" - the GLuint texture associated with the UV plane of an NV12 texture - * "SDL.texture.opengles2.texture_u" - the GLuint texture associated with the U plane of a YUV texture - * "SDL.texture.opengles2.texture_v" - the GLuint texture associated with the V plane of a YUV texture + * "SDL.texture.opengles2.texture" (number) - the GLuint texture associated with the texture + * "SDL.texture.opengles2.texture_uv" (number) - the GLuint texture associated with the UV plane of an NV12 texture + * "SDL.texture.opengles2.texture_u" (number) - the GLuint texture associated with the U plane of a YUV texture + * "SDL.texture.opengles2.texture_v" (number) - the GLuint texture associated with the V plane of a YUV texture * ``` * * \param texture the texture to query diff --git a/include/SDL3/SDL_video.h b/include/SDL3/SDL_video.h index e0363eccd..e8db562df 100644 --- a/include/SDL3/SDL_video.h +++ b/include/SDL3/SDL_video.h @@ -938,58 +938,58 @@ extern DECLSPEC SDL_Window *SDLCALL SDL_GetWindowParent(SDL_Window *window); * * On Android: * ``` - * "SDL.window.android.window" - the ANativeWindow associated with the window - * "SDL.window.android.surface" - the EGLSurface associated with the window + * "SDL.window.android.window" (pointer) - the ANativeWindow associated with the window + * "SDL.window.android.surface" (pointer) - the EGLSurface associated with the window * ``` * * On iOS: * ``` - * "SDL.window.uikit.window" - the (__unsafe_unretained) UIWindow associated with the window - * "SDL.window.uikit.metal_view_tag" - the NSInteger tag assocated with metal views on the window + * "SDL.window.uikit.window" (pointer) - the (__unsafe_unretained) UIWindow associated with the window + * "SDL.window.uikit.metal_view_tag" (number) - the NSInteger tag assocated with metal views on the window * ``` * * On KMS/DRM: * ``` - * "SDL.window.kmsdrm.dev_index" - the device index associated with the window (e.g. the X in /dev/dri/cardX) - * "SDL.window.kmsdrm.drm_fd" - the DRM FD associated with the window - * "SDL.window.kmsdrm.gbm_dev" - the GBM device associated with the window + * "SDL.window.kmsdrm.dev_index" (number) - the device index associated with the window (e.g. the X in /dev/dri/cardX) + * "SDL.window.kmsdrm.drm_fd" (number) - the DRM FD associated with the window + * "SDL.window.kmsdrm.gbm_dev" (pointer) - the GBM device associated with the window * ``` * * On macOS: * ``` - * "SDL.window.cocoa.window" - the (__unsafe_unretained) NSWindow associated with the window - * "SDL.window.cocoa.metal_view_tag" - the NSInteger tag assocated with metal views on the window + * "SDL.window.cocoa.window" (pointer) - the (__unsafe_unretained) NSWindow associated with the window + * "SDL.window.cocoa.metal_view_tag" (number) - the NSInteger tag assocated with metal views on the window * ``` * * On Vivante: * ``` - * "SDL.window.vivante.display" - the EGLNativeDisplayType associated with the window - * "SDL.window.vivante.window" - the EGLNativeWindowType associated with the window - * "SDL.window.vivante.surface" - the EGLSurface associated with the window + * "SDL.window.vivante.display" (pointer) - the EGLNativeDisplayType associated with the window + * "SDL.window.vivante.window" (pointer) - the EGLNativeWindowType associated with the window + * "SDL.window.vivante.surface" (pointer) - the EGLSurface associated with the window * ``` * * On UWP: * ``` - * "SDL.window.winrt.window" - the IInspectable CoreWindow associated with the window + * "SDL.window.winrt.window" (pointer) - the IInspectable CoreWindow associated with the window * ``` * * On Windows: * ``` - * "SDL.window.win32.hwnd" - the HWND associated with the window - * "SDL.window.win32.hdc" - the HDC associated with the window - * "SDL.window.win32.instance" - the HINSTANCE associated with the window + * "SDL.window.win32.hwnd" (pointer) - the HWND associated with the window + * "SDL.window.win32.hdc" (pointer) - the HDC associated with the window + * "SDL.window.win32.instance" (pointer) - the HINSTANCE associated with the window * ``` * * On Wayland: * ``` - * "SDL.window.wayland.registry" - the wl_registry associated with the window - * "SDL.window.wayland.display" - the wl_display associated with the window - * "SDL.window.wayland.surface" - the wl_surface associated with the window - * "SDL.window.wayland.egl_window" - the wl_egl_window associated with the window - * "SDL.window.wayland.xdg_surface" - the xdg_surface associated with the window - * "SDL.window.wayland.xdg_toplevel" - the xdg_toplevel role associated with the window - * "SDL.window.wayland.xdg_popup" - the xdg_popup role associated with the window - * "SDL.window.wayland.xdg_positioner" - the xdg_positioner associated with the window, in popup mode + * "SDL.window.wayland.registry" (pointer) - the wl_registry associated with the window + * "SDL.window.wayland.display" (pointer) - the wl_display associated with the window + * "SDL.window.wayland.surface" (pointer) - the wl_surface associated with the window + * "SDL.window.wayland.egl_window" (pointer) - the wl_egl_window associated with the window + * "SDL.window.wayland.xdg_surface" (pointer) - the xdg_surface associated with the window + * "SDL.window.wayland.xdg_toplevel" (pointer) - the xdg_toplevel role associated with the window + * "SDL.window.wayland.xdg_popup" (pointer) - the xdg_popup role associated with the window + * "SDL.window.wayland.xdg_positioner" (pointer) - the xdg_positioner associated with the window, in popup mode * ``` * * Note: The xdg_* window objects do not internally persist across window show/hide calls. @@ -997,9 +997,9 @@ extern DECLSPEC SDL_Window *SDLCALL SDL_GetWindowParent(SDL_Window *window); * * On X11: * ``` - * "SDL.window.x11.display" - the X11 Display associated with the window - * "SDL.window.x11.screen" - the screen number associated with the window - * "SDL.window.x11.window" - the X11 Window associated with the window + * "SDL.window.x11.display" (pointer) - the X11 Display associated with the window + * "SDL.window.x11.screen" (number) - the screen number associated with the window + * "SDL.window.x11.window" (number) - the X11 Window associated with the window * ``` * * \param window the window to query diff --git a/src/SDL_properties.c b/src/SDL_properties.c index de54ee8c3..5b47b597a 100644 --- a/src/SDL_properties.c +++ b/src/SDL_properties.c @@ -25,7 +25,15 @@ typedef struct { - void *value; + SDL_PropertyType type; + + union { + void *pointer_value; + char *string_value; + Sint64 number_value; + float float_value; + } value; + void (SDLCALL *cleanup)(void *userdata, void *value); void *userdata; } SDL_Property; @@ -45,8 +53,19 @@ static SDL_PropertiesID SDL_global_properties; static void SDL_FreeProperty(const void *key, const void *value, void *data) { SDL_Property *property = (SDL_Property *)value; - if (property->cleanup) { - property->cleanup(property->userdata, property->value); + if (property) { + switch (property->type) { + case SDL_PROPERTY_TYPE_POINTER: + if (property->cleanup) { + property->cleanup(property->userdata, property->value.pointer_value); + } + break; + case SDL_PROPERTY_TYPE_STRING: + SDL_free(property->value.string_value); + break; + default: + break; + } } SDL_free((void *)key); SDL_free((void *)value); @@ -196,21 +215,17 @@ void SDL_UnlockProperties(SDL_PropertiesID props) SDL_UnlockMutex(properties->lock); } -int SDL_SetProperty(SDL_PropertiesID props, const char *name, void *value) -{ - return SDL_SetPropertyWithCleanup(props, name, value, NULL, NULL); -} - -int SDL_SetPropertyWithCleanup(SDL_PropertiesID props, const char *name, void *value, void (SDLCALL *cleanup)(void *userdata, void *value), void *userdata) +static int SDL_PrivateSetProperty(SDL_PropertiesID props, const char *name, SDL_Property *property) { SDL_Properties *properties = NULL; - SDL_Property *property = NULL; int result = 0; if (!props) { + SDL_FreeProperty(NULL, property, NULL); return SDL_InvalidParamError("props"); } if (!name || !*name) { + SDL_FreeProperty(NULL, property, NULL); return SDL_InvalidParamError("name"); } @@ -219,20 +234,10 @@ int SDL_SetPropertyWithCleanup(SDL_PropertiesID props, const char *name, void *v SDL_UnlockRWLock(SDL_properties_lock); if (!properties) { + SDL_FreeProperty(NULL, property, NULL); return SDL_InvalidParamError("props"); } - if (value) { - property = (SDL_Property *)SDL_malloc(sizeof(*property)); - if (!property) { - return SDL_OutOfMemory(); - } - - property->value = value; - property->cleanup = cleanup; - property->userdata = userdata; - } - SDL_LockMutex(properties->lock); { SDL_RemoveFromHashTable(properties->props, name); @@ -249,18 +254,98 @@ int SDL_SetPropertyWithCleanup(SDL_PropertiesID props, const char *name, void *v return result; } -void *SDL_GetProperty(SDL_PropertiesID props, const char *name) +int SDL_SetPropertyWithCleanup(SDL_PropertiesID props, const char *name, void *value, void (SDLCALL *cleanup)(void *userdata, void *value), void *userdata) +{ + SDL_Property *property; + + if (!value) { + return SDL_ClearProperty(props, name); + } + + property = (SDL_Property *)SDL_calloc(1, sizeof(*property)); + if (!property) { + return SDL_OutOfMemory(); + } + property->type = SDL_PROPERTY_TYPE_POINTER; + property->value.pointer_value = value; + property->cleanup = cleanup; + property->userdata = userdata; + return SDL_PrivateSetProperty(props, name, property); +} + +int SDL_SetProperty(SDL_PropertiesID props, const char *name, void *value) +{ + SDL_Property *property; + + if (!value) { + return SDL_ClearProperty(props, name); + } + + property = (SDL_Property *)SDL_calloc(1, sizeof(*property)); + if (!property) { + return SDL_OutOfMemory(); + } + property->type = SDL_PROPERTY_TYPE_POINTER; + property->value.pointer_value = value; + return SDL_PrivateSetProperty(props, name, property); +} + + +int SDL_SetStringProperty(SDL_PropertiesID props, const char *name, const char *value) +{ + SDL_Property *property; + + if (!value) { + return SDL_ClearProperty(props, name); + } + + property = (SDL_Property *)SDL_calloc(1, sizeof(*property)); + if (!property) { + return SDL_OutOfMemory(); + } + property->type = SDL_PROPERTY_TYPE_STRING; + property->value.string_value = SDL_strdup(value); + if (!property->value.string_value) { + SDL_free(property); + return SDL_OutOfMemory(); + } + return SDL_PrivateSetProperty(props, name, property); +} + +int SDL_SetNumberProperty(SDL_PropertiesID props, const char *name, Sint64 value) +{ + SDL_Property *property = (SDL_Property *)SDL_calloc(1, sizeof(*property)); + if (!property) { + return SDL_OutOfMemory(); + } + property->type = SDL_PROPERTY_TYPE_NUMBER; + property->value.number_value = value; + return SDL_PrivateSetProperty(props, name, property); +} + +int SDL_SetFloatProperty(SDL_PropertiesID props, const char *name, float value) +{ + SDL_Property *property = (SDL_Property *)SDL_calloc(1, sizeof(*property)); + if (!property) { + return SDL_OutOfMemory(); + } + property->type = SDL_PROPERTY_TYPE_FLOAT; + property->value.float_value = value; + return SDL_PrivateSetProperty(props, name, property); +} + +SDL_PropertyType SDL_GetPropertyType(SDL_PropertiesID props, const char *name) { SDL_Properties *properties = NULL; - void *value = NULL; + SDL_PropertyType type = SDL_PROPERTY_TYPE_INVALID; if (!props) { SDL_InvalidParamError("props"); - return NULL; + return SDL_PROPERTY_TYPE_INVALID; } if (!name || !*name) { SDL_InvalidParamError("name"); - return NULL; + return SDL_PROPERTY_TYPE_INVALID; } SDL_LockRWLockForReading(SDL_properties_lock); @@ -269,7 +354,44 @@ void *SDL_GetProperty(SDL_PropertiesID props, const char *name) if (!properties) { SDL_InvalidParamError("props"); - return NULL; + return SDL_PROPERTY_TYPE_INVALID; + } + + SDL_LockMutex(properties->lock); + { + SDL_Property *property = NULL; + if (SDL_FindInHashTable(properties->props, name, (const void **)&property)) { + type = property->type; + } else { + SDL_SetError("Couldn't find property named %s", name); + } + } + SDL_UnlockMutex(properties->lock); + + return type; +} + +void *SDL_GetProperty(SDL_PropertiesID props, const char *name, void *default_value) +{ + SDL_Properties *properties = NULL; + void *value = default_value; + + if (!props) { + SDL_InvalidParamError("props"); + return value; + } + if (!name || !*name) { + SDL_InvalidParamError("name"); + return value; + } + + SDL_LockRWLockForReading(SDL_properties_lock); + SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, (const void **)&properties); + SDL_UnlockRWLock(SDL_properties_lock); + + if (!properties) { + SDL_InvalidParamError("props"); + return value; } /* Note that taking the lock here only guarantees that we won't read the @@ -280,7 +402,140 @@ void *SDL_GetProperty(SDL_PropertiesID props, const char *name) { SDL_Property *property = NULL; if (SDL_FindInHashTable(properties->props, name, (const void **)&property)) { - value = property->value; + if (property->type == SDL_PROPERTY_TYPE_POINTER) { + value = property->value.pointer_value; + } else { + SDL_SetError("Property %s isn't a pointer value", name); + } + } else { + SDL_SetError("Couldn't find property named %s", name); + } + } + SDL_UnlockMutex(properties->lock); + + return value; +} + +const char *SDL_GetStringProperty(SDL_PropertiesID props, const char *name, const char *default_value) +{ + SDL_Properties *properties = NULL; + const char *value = default_value; + + if (!props) { + SDL_InvalidParamError("props"); + return value; + } + if (!name || !*name) { + SDL_InvalidParamError("name"); + return value; + } + + SDL_LockRWLockForReading(SDL_properties_lock); + SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, (const void **)&properties); + SDL_UnlockRWLock(SDL_properties_lock); + + if (!properties) { + SDL_InvalidParamError("props"); + return value; + } + + /* Note that taking the lock here only guarantees that we won't read the + * hashtable while it's being modified. The value itself can easily be + * freed from another thread after it is returned here. + * + * FIXME: Should we SDL_strdup() the return value to avoid this? + */ + SDL_LockMutex(properties->lock); + { + SDL_Property *property = NULL; + if (SDL_FindInHashTable(properties->props, name, (const void **)&property)) { + if (property->type == SDL_PROPERTY_TYPE_STRING) { + value = property->value.string_value; + } else { + SDL_SetError("Property %s isn't a string value", name); + } + } else { + SDL_SetError("Couldn't find property named %s", name); + } + } + SDL_UnlockMutex(properties->lock); + + return value; +} + +Sint64 SDL_GetNumberProperty(SDL_PropertiesID props, const char *name, Sint64 default_value) +{ + SDL_Properties *properties = NULL; + Sint64 value = default_value; + + if (!props) { + SDL_InvalidParamError("props"); + return value; + } + if (!name || !*name) { + SDL_InvalidParamError("name"); + return value; + } + + SDL_LockRWLockForReading(SDL_properties_lock); + SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, (const void **)&properties); + SDL_UnlockRWLock(SDL_properties_lock); + + if (!properties) { + SDL_InvalidParamError("props"); + return value; + } + + SDL_LockMutex(properties->lock); + { + SDL_Property *property = NULL; + if (SDL_FindInHashTable(properties->props, name, (const void **)&property)) { + if (property->type == SDL_PROPERTY_TYPE_NUMBER) { + value = property->value.number_value; + } else { + SDL_SetError("Property %s isn't a string value", name); + } + } else { + SDL_SetError("Couldn't find property named %s", name); + } + } + SDL_UnlockMutex(properties->lock); + + return value; +} + +float SDL_GetFloatProperty(SDL_PropertiesID props, const char *name, float default_value) +{ + SDL_Properties *properties = NULL; + float value = default_value; + + if (!props) { + SDL_InvalidParamError("props"); + return value; + } + if (!name || !*name) { + SDL_InvalidParamError("name"); + return value; + } + + SDL_LockRWLockForReading(SDL_properties_lock); + SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, (const void **)&properties); + SDL_UnlockRWLock(SDL_properties_lock); + + if (!properties) { + SDL_InvalidParamError("props"); + return value; + } + + SDL_LockMutex(properties->lock); + { + SDL_Property *property = NULL; + if (SDL_FindInHashTable(properties->props, name, (const void **)&property)) { + if (property->type == SDL_PROPERTY_TYPE_FLOAT) { + value = property->value.float_value; + } else { + SDL_SetError("Property %s isn't a float value", name); + } } else { SDL_SetError("Couldn't find property named %s", name); } @@ -292,7 +547,41 @@ void *SDL_GetProperty(SDL_PropertiesID props, const char *name) int SDL_ClearProperty(SDL_PropertiesID props, const char *name) { - return SDL_SetProperty(props, name, NULL); + return SDL_PrivateSetProperty(props, name, NULL); +} + +int SDL_EnumerateProperties(SDL_PropertiesID props, SDL_EnumeratePropertiesCallback callback, void *userdata) +{ + SDL_Properties *properties = NULL; + + if (!props) { + return SDL_InvalidParamError("props"); + } + if (!callback) { + return SDL_InvalidParamError("callback"); + } + + SDL_LockRWLockForReading(SDL_properties_lock); + SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, (const void **)&properties); + SDL_UnlockRWLock(SDL_properties_lock); + + if (!properties) { + return SDL_InvalidParamError("props"); + } + + SDL_LockMutex(properties->lock); + { + void *iter; + const void *key, *value; + + iter = NULL; + while (SDL_IterateHashTable(properties->props, &key, &value, &iter)) { + callback(userdata, props, (const char *)key); + } + } + SDL_UnlockMutex(properties->lock); + + return 0; } void SDL_DestroyProperties(SDL_PropertiesID props) diff --git a/src/core/linux/SDL_fcitx.c b/src/core/linux/SDL_fcitx.c index 64a200e97..5f67ffb04 100644 --- a/src/core/linux/SDL_fcitx.c +++ b/src/core/linux/SDL_fcitx.c @@ -428,9 +428,9 @@ void SDL_Fcitx_UpdateTextRect(const SDL_Rect *rect) #ifdef SDL_VIDEO_DRIVER_X11 { SDL_PropertiesID props = SDL_GetWindowProperties(focused_win); - Display *x_disp = (Display *)SDL_GetProperty(props, "SDL.window.x11.display"); - int x_screen = (int)(intptr_t)SDL_GetProperty(props, "SDL.window.x11.screen"); - Window x_win = (Window)SDL_GetProperty(props, "SDL.window.x11.window"); + Display *x_disp = (Display *)SDL_GetProperty(props, "SDL.window.x11.display", NULL); + int x_screen = SDL_GetNumberProperty(props, "SDL.window.x11.screen", 0); + Window x_win = SDL_GetNumberProperty(props, "SDL.window.x11.window", 0); Window unused; if (x_disp && x_win) { X11_XTranslateCoordinates(x_disp, x_win, RootWindow(x_disp, x_screen), 0, 0, &x, &y, &unused); diff --git a/src/core/linux/SDL_ibus.c b/src/core/linux/SDL_ibus.c index 9b8214f73..d1ed37b63 100644 --- a/src/core/linux/SDL_ibus.c +++ b/src/core/linux/SDL_ibus.c @@ -705,9 +705,9 @@ void SDL_IBus_UpdateTextRect(const SDL_Rect *rect) #ifdef SDL_VIDEO_DRIVER_X11 { SDL_PropertiesID props = SDL_GetWindowProperties(focused_win); - Display *x_disp = (Display *)SDL_GetProperty(props, "SDL.window.x11.display"); - int x_screen = (int)(intptr_t)SDL_GetProperty(props, "SDL.window.x11.screen"); - Window x_win = (Window)SDL_GetProperty(props, "SDL.window.x11.window"); + Display *x_disp = (Display *)SDL_GetProperty(props, "SDL.window.x11.display", NULL); + int x_screen = SDL_GetNumberProperty(props, "SDL.window.x11.screen", 0); + Window x_win = SDL_GetNumberProperty(props, "SDL.window.x11.window", 0); Window unused; if (x_disp && x_win) { diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym index 972a6ee45..f0dbaf6d7 100644 --- a/src/dynapi/SDL_dynapi.sym +++ b/src/dynapi/SDL_dynapi.sym @@ -956,6 +956,14 @@ SDL3_0.0.0 { SDL_GetPenName; SDL_GetPenCapabilities; SDL_GetPenType; + SDL_SetStringProperty; + SDL_SetNumberProperty; + SDL_SetFloatProperty; + SDL_GetPropertyType; + SDL_GetStringProperty; + SDL_GetNumberProperty; + SDL_GetFloatProperty; + SDL_EnumerateProperties; # extra symbols go here (don't modify this line) local: *; }; diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 41a95138b..8c7f5ea86 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -981,3 +981,11 @@ #define SDL_GetPenName SDL_GetPenName_REAL #define SDL_GetPenCapabilities SDL_GetPenCapabilities_REAL #define SDL_GetPenType SDL_GetPenType_REAL +#define SDL_SetStringProperty SDL_SetStringProperty_REAL +#define SDL_SetNumberProperty SDL_SetNumberProperty_REAL +#define SDL_SetFloatProperty SDL_SetFloatProperty_REAL +#define SDL_GetPropertyType SDL_GetPropertyType_REAL +#define SDL_GetStringProperty SDL_GetStringProperty_REAL +#define SDL_GetNumberProperty SDL_GetNumberProperty_REAL +#define SDL_GetFloatProperty SDL_GetFloatProperty_REAL +#define SDL_EnumerateProperties SDL_EnumerateProperties_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 07f1bd1e2..3314f71bd 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -961,7 +961,7 @@ SDL_DYNAPI_PROC(SDL_PropertiesID,SDL_CreateProperties,(void),(),return) SDL_DYNAPI_PROC(int,SDL_LockProperties,(SDL_PropertiesID a),(a),return) SDL_DYNAPI_PROC(void,SDL_UnlockProperties,(SDL_PropertiesID a),(a),) SDL_DYNAPI_PROC(int,SDL_SetProperty,(SDL_PropertiesID a, const char *b, void *c),(a,b,c),return) -SDL_DYNAPI_PROC(void*,SDL_GetProperty,(SDL_PropertiesID a, const char *b),(a,b),return) +SDL_DYNAPI_PROC(void*,SDL_GetProperty,(SDL_PropertiesID a, const char *b, void *c),(a,b,c),return) SDL_DYNAPI_PROC(void,SDL_DestroyProperties,(SDL_PropertiesID a),(a),) SDL_DYNAPI_PROC(SDL_PropertiesID,SDL_GetAudioStreamProperties,(SDL_AudioStream *a),(a),return) SDL_DYNAPI_PROC(SDL_PropertiesID,SDL_GetGamepadProperties,(SDL_Gamepad *a),(a),return) @@ -1006,3 +1006,11 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_PenConnected,(SDL_PenID a),(a),return) SDL_DYNAPI_PROC(const char*,SDL_GetPenName,(SDL_PenID a),(a),return) SDL_DYNAPI_PROC(Uint32,SDL_GetPenCapabilities,(SDL_PenID a, SDL_PenCapabilityInfo *b),(a,b),return) SDL_DYNAPI_PROC(SDL_PenSubtype,SDL_GetPenType,(SDL_PenID a),(a),return) +SDL_DYNAPI_PROC(int,SDL_SetStringProperty,(SDL_PropertiesID a, const char *b, const char *c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_SetNumberProperty,(SDL_PropertiesID a, const char *b, Sint64 c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_SetFloatProperty,(SDL_PropertiesID a, const char *b, float c),(a,b,c),return) +SDL_DYNAPI_PROC(SDL_PropertyType,SDL_GetPropertyType,(SDL_PropertiesID a, const char *b),(a,b),return) +SDL_DYNAPI_PROC(const char*,SDL_GetStringProperty,(SDL_PropertiesID a, const char *b, const char *c),(a,b,c),return) +SDL_DYNAPI_PROC(Sint64,SDL_GetNumberProperty,(SDL_PropertiesID a, const char *b, Sint64 c),(a,b,c),return) +SDL_DYNAPI_PROC(float,SDL_GetFloatProperty,(SDL_PropertiesID a, const char *b, float c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_EnumerateProperties,(SDL_PropertiesID a, SDL_EnumeratePropertiesCallback b, void *c),(a,b,c),return) diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index 55904a38c..8f987e84d 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -994,7 +994,7 @@ SDL_Renderer *SDL_CreateSoftwareRenderer(SDL_Surface *surface) SDL_Renderer *SDL_GetRenderer(SDL_Window *window) { - return (SDL_Renderer *)SDL_GetProperty(SDL_GetWindowProperties(window), SDL_WINDOWRENDERDATA); + return (SDL_Renderer *)SDL_GetProperty(SDL_GetWindowProperties(window), SDL_WINDOWRENDERDATA, NULL); } SDL_Window *SDL_GetRenderWindow(SDL_Renderer *renderer) diff --git a/src/render/direct3d/SDL_render_d3d.c b/src/render/direct3d/SDL_render_d3d.c index 4fd16b4e9..7d6428932 100644 --- a/src/render/direct3d/SDL_render_d3d.c +++ b/src/render/direct3d/SDL_render_d3d.c @@ -1602,7 +1602,7 @@ SDL_Renderer *D3D_CreateRenderer(SDL_Window *window, Uint32 flags) } SDL_zero(pparams); - pparams.hDeviceWindow = (HWND)SDL_GetProperty(SDL_GetWindowProperties(window), "SDL.window.win32.hwnd"); + pparams.hDeviceWindow = (HWND)SDL_GetProperty(SDL_GetWindowProperties(window), "SDL.window.win32.hwnd", NULL); pparams.BackBufferWidth = w; pparams.BackBufferHeight = h; pparams.BackBufferCount = 1; diff --git a/src/render/direct3d11/SDL_render_d3d11.c b/src/render/direct3d11/SDL_render_d3d11.c index 5b3b10e8f..4561dfe30 100644 --- a/src/render/direct3d11/SDL_render_d3d11.c +++ b/src/render/direct3d11/SDL_render_d3d11.c @@ -825,7 +825,7 @@ static HRESULT D3D11_CreateSwapChain(SDL_Renderer *renderer, int w, int h) #endif } else { #if defined(__WIN32__) || defined(__WINGDK__) - HWND hwnd = (HWND)SDL_GetProperty(SDL_GetWindowProperties(renderer->window), "SDL.window.win32.hwnd"); + HWND hwnd = (HWND)SDL_GetProperty(SDL_GetWindowProperties(renderer->window), "SDL.window.win32.hwnd", NULL); result = IDXGIFactory2_CreateSwapChainForHwnd(data->dxgiFactory, (IUnknown *)data->d3dDevice, diff --git a/src/render/direct3d11/SDL_render_winrt.cpp b/src/render/direct3d11/SDL_render_winrt.cpp index 4ecd41908..34992d99c 100644 --- a/src/render/direct3d11/SDL_render_winrt.cpp +++ b/src/render/direct3d11/SDL_render_winrt.cpp @@ -44,7 +44,7 @@ using namespace Windows::Graphics::Display; extern "C" void * D3D11_GetCoreWindowFromSDLRenderer(SDL_Renderer *renderer) { - IInspectable *window = (IInspectable *)SDL_GetProperty(SDL_GetWindowProperties(renderer->window), "SDL.window.winrt.window"); + IInspectable *window = (IInspectable *)SDL_GetProperty(SDL_GetWindowProperties(renderer->window), "SDL.window.winrt.window", NULL); ABI::Windows::UI::Core::ICoreWindow *coreWindow = NULL; if (!window || FAILED(window->QueryInterface(&coreWindow))) { return NULL; diff --git a/src/render/direct3d12/SDL_render_d3d12.c b/src/render/direct3d12/SDL_render_d3d12.c index bda1fbe0f..1442be58e 100644 --- a/src/render/direct3d12/SDL_render_d3d12.c +++ b/src/render/direct3d12/SDL_render_d3d12.c @@ -1178,7 +1178,7 @@ static HRESULT D3D12_CreateSwapChain(SDL_Renderer *renderer, int w, int h) swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT | /* To support SetMaximumFrameLatency */ DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING; /* To support presenting with allow tearing on */ - HWND hwnd = (HWND)SDL_GetProperty(SDL_GetWindowProperties(renderer->window), "SDL.window.win32.hwnd"); + HWND hwnd = (HWND)SDL_GetProperty(SDL_GetWindowProperties(renderer->window), "SDL.window.win32.hwnd", NULL); result = D3D_CALL(data->dxgiFactory, CreateSwapChainForHwnd, (IUnknown *)data->commandQueue, diff --git a/src/render/metal/SDL_render_metal.m b/src/render/metal/SDL_render_metal.m index 606b17f17..a215ff5c6 100644 --- a/src/render/metal/SDL_render_metal.m +++ b/src/render/metal/SDL_render_metal.m @@ -1626,9 +1626,9 @@ static int METAL_SetVSync(SDL_Renderer *renderer, const int vsync) static SDL_MetalView GetWindowView(SDL_Window *window) { #ifdef SDL_VIDEO_DRIVER_COCOA - NSWindow *nswindow = (__bridge NSWindow *)SDL_GetProperty(SDL_GetWindowProperties(window), "SDL.window.cocoa.window"); - NSInteger tag = (NSInteger)SDL_GetProperty(SDL_GetWindowProperties(window), "SDL.window.cocoa.metal_view_tag"); - if (nswindow) { + NSWindow *nswindow = (__bridge NSWindow *)SDL_GetProperty(SDL_GetWindowProperties(window), "SDL.window.cocoa.window", NULL); + NSInteger tag = (NSInteger)SDL_GetNumberProperty(SDL_GetWindowProperties(window), "SDL.window.cocoa.metal_view_tag", 0); + if (nswindow && tag) { NSView *view = nswindow.contentView; if (view.subviews.count > 0) { view = view.subviews[0]; @@ -1640,9 +1640,9 @@ static SDL_MetalView GetWindowView(SDL_Window *window) #endif #ifdef SDL_VIDEO_DRIVER_UIKIT - UIWindow *uiwindow = (__bridge UIWindow *)SDL_GetProperty(SDL_GetWindowProperties(window), "SDL.window.uikit.window"); - NSInteger tag = (NSInteger)SDL_GetProperty(SDL_GetWindowProperties(window), "SDL.window.uikit.metal_view_tag"); - if (uiwindow) { + UIWindow *uiwindow = (__bridge UIWindow *)SDL_GetProperty(SDL_GetWindowProperties(window), "SDL.window.uikit.window", NULL); + NSInteger tag = (NSInteger)SDL_GetNumberProperty(SDL_GetWindowProperties(window), "SDL.window.uikit.metal_view_tag", 0); + if (uiwindow && tag) { UIView *view = uiwindow.rootViewController.view; if (view.tag == tag) { return (SDL_MetalView)CFBridgingRetain(view); diff --git a/src/render/opengl/SDL_render_gl.c b/src/render/opengl/SDL_render_gl.c index bc86432f5..523e8ac7e 100644 --- a/src/render/opengl/SDL_render_gl.c +++ b/src/render/opengl/SDL_render_gl.c @@ -519,9 +519,9 @@ static int GL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) data->texh = (GLfloat)texture->h / texture_h; } SDL_PropertiesID props = SDL_GetTextureProperties(texture); - SDL_SetProperty(props, "SDL.texture.opengl.texture", (void *)(uintptr_t)data->texture); - SDL_SetProperty(props, "SDL.texture.opengl.tex_w", (void *)(uintptr_t)(Uint32)(data->texw * 65536)); - SDL_SetProperty(props, "SDL.texture.opengl.tex_h", (void *)(uintptr_t)(Uint32)(data->texh * 65536)); + SDL_SetNumberProperty(props, "SDL.texture.opengl.texture", data->texture); + SDL_SetFloatProperty(props, "SDL.texture.opengl.tex_w", data->texw); + SDL_SetFloatProperty(props, "SDL.texture.opengl.tex_h", data->texh); data->format = format; data->formattype = type; @@ -594,7 +594,7 @@ static int GL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) GL_CLAMP_TO_EDGE); renderdata->glTexImage2D(textype, 0, internalFormat, (texture_w + 1) / 2, (texture_h + 1) / 2, 0, format, type, NULL); - SDL_SetProperty(props, "SDL.texture.opengl.texture_u", (void *)(uintptr_t)data->utexture); + SDL_SetNumberProperty(props, "SDL.texture.opengl.texture_u", data->utexture); renderdata->glBindTexture(textype, data->vtexture); renderdata->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, @@ -607,7 +607,7 @@ static int GL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) GL_CLAMP_TO_EDGE); renderdata->glTexImage2D(textype, 0, internalFormat, (texture_w + 1) / 2, (texture_h + 1) / 2, 0, format, type, NULL); - SDL_SetProperty(props, "SDL.texture.opengl.texture_v", (void *)(uintptr_t)data->vtexture); + SDL_SetNumberProperty(props, "SDL.texture.opengl.texture_v", data->vtexture); } if (texture->format == SDL_PIXELFORMAT_NV12 || diff --git a/src/render/opengles2/SDL_render_gles2.c b/src/render/opengles2/SDL_render_gles2.c index 21d04c45c..cb03179ef 100644 --- a/src/render/opengles2/SDL_render_gles2.c +++ b/src/render/opengles2/SDL_render_gles2.c @@ -1499,7 +1499,7 @@ static int GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); renderdata->glTexImage2D(data->texture_type, 0, format, (texture->w + 1) / 2, (texture->h + 1) / 2, 0, format, type, NULL); - SDL_SetProperty(SDL_GetTextureProperties(texture), "SDL.texture.opengles2.texture_v", (void *)(uintptr_t)data->texture_v); + SDL_SetNumberProperty(SDL_GetTextureProperties(texture), "SDL.texture.opengles2.texture_v", data->texture_v); renderdata->glGenTextures(1, &data->texture_u); if (GL_CheckError("glGenTexures()", renderer) < 0) { @@ -1515,7 +1515,7 @@ static int GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) if (GL_CheckError("glTexImage2D()", renderer) < 0) { return -1; } - SDL_SetProperty(SDL_GetTextureProperties(texture), "SDL.texture.opengles2.texture_u", (void *)(uintptr_t)data->texture_u); + SDL_SetNumberProperty(SDL_GetTextureProperties(texture), "SDL.texture.opengles2.texture_u", data->texture_u); } else if (data->nv12) { renderdata->glGenTextures(1, &data->texture_u); @@ -1532,7 +1532,7 @@ static int GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) if (GL_CheckError("glTexImage2D()", renderer) < 0) { return -1; } - SDL_SetProperty(SDL_GetTextureProperties(texture), "SDL.texture.opengles2.texture_uv", (void *)(uintptr_t)data->texture_u); + SDL_SetNumberProperty(SDL_GetTextureProperties(texture), "SDL.texture.opengles2.texture_uv", data->texture_u); } #endif @@ -1553,7 +1553,7 @@ static int GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) return -1; } } - SDL_SetProperty(SDL_GetTextureProperties(texture), "SDL.texture.opengles2.texture", (void *)(uintptr_t)data->texture); + SDL_SetNumberProperty(SDL_GetTextureProperties(texture), "SDL.texture.opengles2.texture", data->texture); if (texture->access == SDL_TEXTUREACCESS_TARGET) { data->fbo = GLES2_GetFBO(renderer->driverdata, texture->w, texture->h); diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index a293b7dc4..16010b810 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -226,7 +226,7 @@ static int SDL_CreateWindowTexture(SDL_VideoDevice *_this, SDL_Window *window, U { SDL_RendererInfo info; SDL_PropertiesID props = SDL_GetWindowProperties(window); - SDL_WindowTextureData *data = (SDL_WindowTextureData *)SDL_GetProperty(props, SDL_WINDOWTEXTUREDATA); + SDL_WindowTextureData *data = (SDL_WindowTextureData *)SDL_GetProperty(props, SDL_WINDOWTEXTUREDATA, NULL); const SDL_bool transparent = (window->flags & SDL_WINDOW_TRANSPARENT) ? SDL_TRUE : SDL_FALSE; int i; int w, h; @@ -349,7 +349,7 @@ static int SDL_UpdateWindowTexture(SDL_VideoDevice *unused, SDL_Window *window, SDL_GetWindowSizeInPixels(window, &w, &h); - data = SDL_GetProperty(SDL_GetWindowProperties(window), SDL_WINDOWTEXTUREDATA); + data = SDL_GetProperty(SDL_GetWindowProperties(window), SDL_WINDOWTEXTUREDATA, NULL); if (!data || !data->texture) { return SDL_SetError("No window texture data"); } @@ -381,7 +381,7 @@ int SDL_SetWindowTextureVSync(SDL_Window *window, int vsync) { SDL_WindowTextureData *data; - data = SDL_GetProperty(SDL_GetWindowProperties(window), SDL_WINDOWTEXTUREDATA); + data = SDL_GetProperty(SDL_GetWindowProperties(window), SDL_WINDOWTEXTUREDATA, NULL); if (!data) { return -1; } diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m index c7e004b22..afbfb4352 100644 --- a/src/video/cocoa/SDL_cocoawindow.m +++ b/src/video/cocoa/SDL_cocoawindow.m @@ -1864,7 +1864,7 @@ static int SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, NSWindow SDL_PropertiesID props = SDL_GetWindowProperties(window); SDL_SetProperty(props, "SDL.window.cocoa.window", (__bridge void *)data.nswindow); - SDL_SetProperty(props, "SDL.window.cocoa.metal_view_tag", SDL_METALVIEW_TAG); + SDL_SetNumberProperty(props, "SDL.window.cocoa.metal_view_tag", SDL_METALVIEW_TAG); /* All done! */ window->driverdata = (SDL_WindowData *)CFBridgingRetain(data); diff --git a/src/video/dummy/SDL_nullframebuffer.c b/src/video/dummy/SDL_nullframebuffer.c index d51b3c408..e67954e06 100644 --- a/src/video/dummy/SDL_nullframebuffer.c +++ b/src/video/dummy/SDL_nullframebuffer.c @@ -60,7 +60,7 @@ int SDL_DUMMY_UpdateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window static int frame_number; SDL_Surface *surface; - surface = (SDL_Surface *)SDL_GetProperty(SDL_GetWindowProperties(window), DUMMY_SURFACE); + surface = (SDL_Surface *)SDL_GetProperty(SDL_GetWindowProperties(window), DUMMY_SURFACE, NULL); if (!surface) { return SDL_SetError("Couldn't find dummy surface for window"); } diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c index 544cbff07..ca283c1fe 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvideo.c +++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c @@ -1467,8 +1467,8 @@ int KMSDRM_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window) window->driverdata = windata; SDL_PropertiesID props = SDL_GetWindowProperties(window); - SDL_SetProperty(props, "SDL.window.kmsdrm.dev_index", (void *)(intptr_t)viddata->devindex); - SDL_SetProperty(props, "SDL.window.kmsdrm.drm_fd", (void *)(intptr_t)viddata->drm_fd); + SDL_SetNumberProperty(props, "SDL.window.kmsdrm.dev_index", viddata->devindex); + SDL_SetNumberProperty(props, "SDL.window.kmsdrm.drm_fd", viddata->drm_fd); SDL_SetProperty(props, "SDL.window.kmsdrm.gbm_dev", viddata->gbm_dev); if (!is_vulkan && !vulkan_mode) { /* NON-Vulkan block. */ diff --git a/src/video/n3ds/SDL_n3dsframebuffer.c b/src/video/n3ds/SDL_n3dsframebuffer.c index 502594d66..727dab6a8 100644 --- a/src/video/n3ds/SDL_n3dsframebuffer.c +++ b/src/video/n3ds/SDL_n3dsframebuffer.c @@ -72,7 +72,7 @@ int SDL_N3DS_UpdateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, u32 *framebuffer; u32 bufsize; - surface = (SDL_Surface *)SDL_GetProperty(SDL_GetWindowProperties(window), N3DS_SURFACE); + surface = (SDL_Surface *)SDL_GetProperty(SDL_GetWindowProperties(window), N3DS_SURFACE, NULL); if (!surface) { return SDL_SetError("%s: Unable to get the window surface.", __func__); } diff --git a/src/video/offscreen/SDL_offscreenframebuffer.c b/src/video/offscreen/SDL_offscreenframebuffer.c index cd9604f65..6ca61316f 100644 --- a/src/video/offscreen/SDL_offscreenframebuffer.c +++ b/src/video/offscreen/SDL_offscreenframebuffer.c @@ -61,7 +61,7 @@ int SDL_OFFSCREEN_UpdateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *wi static int frame_number; SDL_Surface *surface; - surface = (SDL_Surface *)SDL_GetProperty(SDL_GetWindowProperties(window), OFFSCREEN_SURFACE); + surface = (SDL_Surface *)SDL_GetProperty(SDL_GetWindowProperties(window), OFFSCREEN_SURFACE, NULL); if (!surface) { return SDL_SetError("Couldn't find offscreen surface for window"); } diff --git a/src/video/uikit/SDL_uikitwindow.m b/src/video/uikit/SDL_uikitwindow.m index 407e6edf4..54ba279bd 100644 --- a/src/video/uikit/SDL_uikitwindow.m +++ b/src/video/uikit/SDL_uikitwindow.m @@ -155,7 +155,7 @@ static int SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, UIWindow SDL_PropertiesID props = SDL_GetWindowProperties(window); SDL_SetProperty(props, "SDL.window.uikit.window", (__bridge void *)data.uiwindow); - SDL_SetProperty(props, "SDL.window.uikit.metal_view_tag", SDL_METALVIEW_TAG); + SDL_SetNumberProperty(props, "SDL.window.uikit.metal_view_tag", SDL_METALVIEW_TAG); return 0; } diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c index 1f3e9090d..0997fc753 100644 --- a/src/video/x11/SDL_x11window.c +++ b/src/video/x11/SDL_x11window.c @@ -386,8 +386,8 @@ static int SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, Window w, SDL_PropertiesID props = SDL_GetWindowProperties(window); int screen = (displaydata ? displaydata->screen : 0); SDL_SetProperty(props, "SDL.window.x11.display", data->videodata->display); - SDL_SetProperty(props, "SDL.window.x11.screen", (void *)(intptr_t)screen); - SDL_SetProperty(props, "SDL.window.x11.window", (void *)(uintptr_t)data->xwindow); + SDL_SetNumberProperty(props, "SDL.window.x11.screen", screen); + SDL_SetNumberProperty(props, "SDL.window.x11.window", data->xwindow); return 0; } diff --git a/test/testautomation_properties.c b/test/testautomation_properties.c index 75ddc35b9..d2936f119 100644 --- a/test/testautomation_properties.c +++ b/test/testautomation_properties.c @@ -11,12 +11,28 @@ /** * Test basic functionality */ +static void SDLCALL count_properties(void *userdata, SDL_PropertiesID props, const char *name) +{ + int *count = (int *)userdata; + ++(*count); +} +static void SDLCALL count_foo_properties(void *userdata, SDL_PropertiesID props, const char *name) +{ + int *count = (int *)userdata; + if (SDL_strcmp(name, "foo") == 0) { + ++(*count); + } +} static int properties_testBasic(void *arg) { SDL_PropertiesID props; char key[2], expected_value[2]; + SDL_PropertyType type; void *value; - int i, result; + const char *value_string; + Sint64 value_number; + float value_float; + int i, result, count; props = SDL_CreateProperties(); SDLTest_AssertPass("Call to SDL_CreateProperties()"); @@ -30,24 +46,130 @@ static int properties_testBasic(void *arg) SDLTest_AssertPass("Call to SDL_SetProperty()"); SDLTest_AssertCheck(result == 0, "Verify property value was set, got: %d", result); - value = SDL_GetProperty(props, key); + value = SDL_GetProperty(props, key, NULL); SDLTest_AssertPass("Call to SDL_GetProperty()"); SDLTest_AssertCheck(value && SDL_strcmp((const char *)value, expected_value) == 0, "Verify property value was set, got %s, expected %s", value ? (const char *)value : "NULL", expected_value); } + count = 0; + SDL_EnumerateProperties(props, count_properties, &count); + SDLTest_AssertCheck(count == 10, + "Verify property count, expected 10, got: %d", count); + for (i = 0; i < 10; ++i) { SDL_snprintf(key, SDL_arraysize(key), "%c", 'a' + i); result = SDL_SetProperty(props, key, NULL); SDLTest_AssertPass("Call to SDL_SetProperty(NULL)"); SDLTest_AssertCheck(result == 0, "Verify property value was set, got: %d", result); - value = SDL_GetProperty(props, key); + value = SDL_GetProperty(props, key, NULL); SDLTest_AssertPass("Call to SDL_GetProperty()"); SDLTest_AssertCheck(value == NULL, "Verify property value was set, got %s, expected NULL", (const char *)value); } + count = 0; + SDL_EnumerateProperties(props, count_properties, &count); + SDLTest_AssertCheck(count == 0, + "Verify property count, expected 0, got: %d", count); + + /* Check default values */ + value = SDL_GetProperty(props, "foo", (void *)0xabcd); + SDLTest_AssertCheck(value == (void *)0xabcd, + "Verify property, expected 0xabcd, got: %p", value); + value_string = SDL_GetStringProperty(props, "foo", "abcd"); + SDLTest_AssertCheck(value_string && SDL_strcmp(value_string, "abcd") == 0, + "Verify string property, expected \"abcd\", got: %s", value_string); + value_number = SDL_GetNumberProperty(props, "foo", 1234); + SDLTest_AssertCheck(value_number == 1234, + "Verify number property, expected 1234, got: %" SDL_PRIu64 "", value_number); + value_float = SDL_GetFloatProperty(props, "foo", 1234.0f); + SDLTest_AssertCheck(value_float == 1234.0f, + "Verify float property, expected 1234, got: %f", value_float); + + /* Check data value */ + SDLTest_AssertPass("Call to SDL_SetProperty(\"foo\", 0x01)"); + SDL_SetProperty(props, "foo", (void *)0x01); + type = SDL_GetPropertyType(props, "foo"); + SDLTest_AssertCheck(type == SDL_PROPERTY_TYPE_POINTER, + "Verify property type, expected %d, got: %d", SDL_PROPERTY_TYPE_POINTER, type); + value = SDL_GetProperty(props, "foo", NULL); + SDLTest_AssertCheck(value == (void *)0x01, + "Verify property, expected 0x01, got: %p", value); + value_string = SDL_GetStringProperty(props, "foo", NULL); + SDLTest_AssertCheck(value_string == NULL, + "Verify string property, expected NULL, got: %s", value_string); + value_number = SDL_GetNumberProperty(props, "foo", 0); + SDLTest_AssertCheck(value_number == 0, + "Verify number property, expected 0, got: %" SDL_PRIu64 "", value_number); + value_float = SDL_GetFloatProperty(props, "foo", 0.0f); + SDLTest_AssertCheck(value_float == 0.0f, + "Verify float property, expected 0, got: %f", value_float); + + /* Check string value */ + SDLTest_AssertPass("Call to SDL_SetStringProperty(\"foo\", \"bar\")"); + SDL_SetStringProperty(props, "foo", "bar"); + type = SDL_GetPropertyType(props, "foo"); + SDLTest_AssertCheck(type == SDL_PROPERTY_TYPE_STRING, + "Verify property type, expected %d, got: %d", SDL_PROPERTY_TYPE_STRING, type); + value = SDL_GetProperty(props, "foo", NULL); + SDLTest_AssertCheck(value == NULL, + "Verify property, expected NULL, got: %p", value); + value_string = SDL_GetStringProperty(props, "foo", NULL); + SDLTest_AssertCheck(value_string != NULL && SDL_strcmp(value_string, "bar") == 0, + "Verify string property, expected \"bar\", got: %s", value_string); + value_number = SDL_GetNumberProperty(props, "foo", 0); + SDLTest_AssertCheck(value_number == 0, + "Verify number property, expected 0, got: %" SDL_PRIu64 "", value_number); + value_float = SDL_GetFloatProperty(props, "foo", 0.0f); + SDLTest_AssertCheck(value_float == 0.0f, + "Verify float property, expected 0, got: %f", value_float); + + /* Check number value */ + SDLTest_AssertPass("Call to SDL_SetNumberProperty(\"foo\", 1)"); + SDL_SetNumberProperty(props, "foo", 1); + type = SDL_GetPropertyType(props, "foo"); + SDLTest_AssertCheck(type == SDL_PROPERTY_TYPE_NUMBER, + "Verify property type, expected %d, got: %d", SDL_PROPERTY_TYPE_NUMBER, type); + value = SDL_GetProperty(props, "foo", NULL); + SDLTest_AssertCheck(value == NULL, + "Verify property, expected NULL, got: %p", value); + value_string = SDL_GetStringProperty(props, "foo", NULL); + SDLTest_AssertCheck(value_string == NULL, + "Verify string property, expected NULL, got: %s", value_string); + value_number = SDL_GetNumberProperty(props, "foo", 0); + SDLTest_AssertCheck(value_number == 1, + "Verify number property, expected 1, got: %" SDL_PRIu64 "", value_number); + value_float = SDL_GetFloatProperty(props, "foo", 0.0f); + SDLTest_AssertCheck(value_float == 0.0f, + "Verify float property, expected 0, got: %f", value_float); + + /* Check float value */ + SDLTest_AssertPass("Call to SDL_SetNumberProperty(\"foo\", 1)"); + SDL_SetFloatProperty(props, "foo", 1.0f); + type = SDL_GetPropertyType(props, "foo"); + SDLTest_AssertCheck(type == SDL_PROPERTY_TYPE_FLOAT, + "Verify property type, expected %d, got: %d", SDL_PROPERTY_TYPE_FLOAT, type); + value = SDL_GetProperty(props, "foo", NULL); + SDLTest_AssertCheck(value == NULL, + "Verify property, expected NULL, got: %p", value); + value_string = SDL_GetStringProperty(props, "foo", NULL); + SDLTest_AssertCheck(value_string == NULL, + "Verify string property, expected NULL, got: %s", value_string); + value_number = SDL_GetNumberProperty(props, "foo", 0); + SDLTest_AssertCheck(value_number == 0, + "Verify number property, expected 0, got: %" SDL_PRIu64 "", value_number); + value_float = SDL_GetFloatProperty(props, "foo", 0.0f); + SDLTest_AssertCheck(value_float == 1.0f, + "Verify string property, expected 1, got: %f", value_float); + + /* Make sure we have exactly one property named foo */ + count = 0; + SDL_EnumerateProperties(props, count_foo_properties, &count); + SDLTest_AssertCheck(count == 1, + "Verify foo property count, expected 1, got: %d", count); + SDL_DestroyProperties(props); return TEST_COMPLETED; @@ -130,7 +252,7 @@ static int properties_testLocking(void *arg) { SDL_Delay(10); SDL_LockProperties(data.props); - value = SDL_GetProperty(data.props, "a"); + value = SDL_GetProperty(data.props, "a", NULL); SDL_UnlockProperties(data.props); if (!value || SDL_strcmp((const char *)value, "thread_loop") == 0) { @@ -144,7 +266,7 @@ static int properties_testLocking(void *arg) SDL_LockProperties(data.props); SDL_SetProperty(data.props, "a", "main"); SDL_Delay(100); - value = SDL_GetProperty(data.props, "a"); + value = SDL_GetProperty(data.props, "a", NULL); SDLTest_AssertCheck(value && SDL_strcmp((const char *)value, "main") == 0, "After 100ms sleep, property is %s, expected 'main'", value ? (const char *)value : "NULL"); SDL_UnlockProperties(data.props); @@ -152,7 +274,7 @@ static int properties_testLocking(void *arg) data.done = SDL_TRUE; SDL_WaitThread(thread, NULL); - value = SDL_GetProperty(data.props, "a"); + value = SDL_GetProperty(data.props, "a", NULL); SDLTest_AssertCheck(value && SDL_strcmp((const char *)value, "thread_done") == 0, "After thread complete, property is %s, expected 'thread_done'", value ? (const char *)value : "NULL"); } diff --git a/test/testautomation_video.c b/test/testautomation_video.c index e5fbdee28..14caeee49 100644 --- a/test/testautomation_video.c +++ b/test/testautomation_video.c @@ -1492,7 +1492,7 @@ static int video_getSetWindowData(void *arg) } /* Get non-existent data */ - result = (char *)SDL_GetProperty(SDL_GetWindowProperties(window), name); + result = (char *)SDL_GetProperty(SDL_GetWindowProperties(window), name, NULL); SDLTest_AssertPass("Call to SDL_GetWindowData(..,%s)", name); SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); @@ -1505,8 +1505,7 @@ static int video_getSetWindowData(void *arg) /* Get data (twice) */ for (iteration = 1; iteration <= 2; iteration++) { - result = (char *)SDL_GetProperty(SDL_GetWindowProperties(window), - name); + result = (char *)SDL_GetProperty(SDL_GetWindowProperties(window), name, NULL); SDLTest_AssertPass("Call to SDL_GetWindowData(..,%s) [iteration %d]", name, iteration); SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, result) == 0, "Validate that correct result was returned; expected: %s, got: %s", referenceUserdata, result); SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); @@ -1521,7 +1520,7 @@ static int video_getSetWindowData(void *arg) } /* Get data again */ - result = (char *)SDL_GetProperty(SDL_GetWindowProperties(window), name); + result = (char *)SDL_GetProperty(SDL_GetWindowProperties(window), name, NULL); SDLTest_AssertPass("Call to SDL_GetWindowData(..,%s) [again]", name); SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, result) == 0, "Validate that correct result was returned; expected: %s, got: %s", referenceUserdata, result); SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); @@ -1541,7 +1540,7 @@ static int video_getSetWindowData(void *arg) SDLTest_AssertCheck(SDL_strcmp(referenceUserdata2, userdata2) == 0, "Validate that userdata2 was not changed, expected: %s, got: %s", referenceUserdata2, userdata2); /* Get new data */ - result = (char *)SDL_GetProperty(SDL_GetWindowProperties(window), name); + result = (char *)SDL_GetProperty(SDL_GetWindowProperties(window), name, NULL); SDLTest_AssertPass("Call to SDL_GetWindowData(..,%s)", name); SDLTest_AssertCheck(SDL_strcmp(referenceUserdata2, result) == 0, "Validate that correct result was returned; expected: %s, got: %s", referenceUserdata2, result); SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); @@ -1561,13 +1560,13 @@ static int video_getSetWindowData(void *arg) SDLTest_AssertCheck(SDL_strcmp(referenceUserdata2, userdata2) == 0, "Validate that userdata2 was not changed, expected: %s, got: %s", referenceUserdata2, userdata2); /* Get non-existent data */ - result = (char *)SDL_GetProperty(SDL_GetWindowProperties(window), name); + result = (char *)SDL_GetProperty(SDL_GetWindowProperties(window), name, NULL); SDLTest_AssertPass("Call to SDL_GetWindowData(..,%s)", name); SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); /* Get non-existent data new name */ - result = (char *)SDL_GetProperty(SDL_GetWindowProperties(window), name2); + result = (char *)SDL_GetProperty(SDL_GetWindowProperties(window), name2, NULL); SDLTest_AssertPass("Call to SDL_GetWindowData(..,%s)", name2); SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); SDLTest_AssertCheck(SDL_strcmp(referenceName2, name2) == 0, "Validate that name2 was not changed, expected: %s, got: %s", referenceName2, name2); @@ -1579,7 +1578,7 @@ static int video_getSetWindowData(void *arg) SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, userdata) == 0, "Validate that userdata was not changed, expected: %s, got: %s", referenceUserdata, userdata); /* Get data (again) */ - result = (char *)SDL_GetProperty(SDL_GetWindowProperties(window), name); + result = (char *)SDL_GetProperty(SDL_GetWindowProperties(window), name, NULL); SDLTest_AssertPass("Call to SDL_GetWindowData(..,%s) [again, after clear]", name); SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, result) == 0, "Validate that correct result was returned; expected: %s, got: %s", referenceUserdata, result); SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); @@ -1605,13 +1604,13 @@ static int video_getSetWindowData(void *arg) checkInvalidParameterError(); /* Get data with NULL name */ - result = (char *)SDL_GetProperty(SDL_GetWindowProperties(window), NULL); + result = (char *)SDL_GetProperty(SDL_GetWindowProperties(window), NULL, NULL); SDLTest_AssertPass("Call to SDL_GetWindowData(name=NULL)"); SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); checkInvalidParameterError(); /* Get data with empty name */ - result = (char *)SDL_GetProperty(SDL_GetWindowProperties(window), ""); + result = (char *)SDL_GetProperty(SDL_GetWindowProperties(window), "", NULL); SDLTest_AssertPass("Call to SDL_GetWindowData(name='')"); SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); checkInvalidParameterError(); diff --git a/test/testffmpeg.c b/test/testffmpeg.c index 1fd3816be..f28d60c35 100644 --- a/test/testffmpeg.c +++ b/test/testffmpeg.c @@ -145,7 +145,7 @@ static SDL_bool CreateWindowAndRenderer(Uint32 window_flags, const char *driver) #endif #ifdef __WIN32__ - d3d11_device = (ID3D11Device *)SDL_GetProperty(SDL_GetRendererProperties(renderer), "SDL.renderer.d3d11.device"); + d3d11_device = (ID3D11Device *)SDL_GetProperty(SDL_GetRendererProperties(renderer), "SDL.renderer.d3d11.device", NULL); if (d3d11_device) { ID3D11Device_AddRef(d3d11_device); ID3D11Device_GetImmediateContext(d3d11_device, &d3d11_context); @@ -457,7 +457,7 @@ static SDL_bool GetTextureForMemoryFrame(AVFrame *frame, SDL_Texture **texture) case SDL_PIXELFORMAT_UNKNOWN: { SDL_PropertiesID props = SDL_GetTextureProperties(*texture); - struct SwsContextContainer *sws_container = (struct SwsContextContainer *)SDL_GetProperty(props, SWS_CONTEXT_CONTAINER_PROPERTY); + struct SwsContextContainer *sws_container = (struct SwsContextContainer *)SDL_GetProperty(props, SWS_CONTEXT_CONTAINER_PROPERTY, NULL); if (!sws_container) { sws_container = (struct SwsContextContainer *)SDL_calloc(1, sizeof(*sws_container)); if (!sws_container) { @@ -625,7 +625,7 @@ static SDL_bool GetTextureForD3D11Frame(AVFrame *frame, SDL_Texture **texture) } } - ID3D11Resource *dx11_resource = SDL_GetProperty(SDL_GetTextureProperties(*texture), "SDL.texture.d3d11.texture"); + ID3D11Resource *dx11_resource = SDL_GetProperty(SDL_GetTextureProperties(*texture), "SDL.texture.d3d11.texture", NULL); if (!dx11_resource) { SDL_SetError("Couldn't get texture ID3D11Resource interface"); return SDL_FALSE;