Added property types: pointer, string, number, float

main
Sam Lantinga 2023-11-12 09:47:31 -08:00
parent 7c80ac6df7
commit 0907f345cb
28 changed files with 737 additions and 152 deletions

View File

@ -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
*

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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) {

View File

@ -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: *;
};

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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,

View File

@ -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);

View File

@ -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 ||

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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");
}

View File

@ -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. */

View File

@ -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__);
}

View File

@ -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");
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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");
}

View File

@ -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();

View File

@ -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;