From 3ccc895645d7b26309e7d7d0b89ed3ed1ae5396c Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 3 Feb 2011 11:16:57 -0800 Subject: [PATCH] Extended SDL_SetWindowData() to allow arbitrary named values. --- include/SDL_video.h | 25 ++++++++++++--- src/video/SDL_sysvideo.h | 10 +++++- src/video/SDL_video.c | 68 ++++++++++++++++++++++++++++++++++------ 3 files changed, 87 insertions(+), 16 deletions(-) diff --git a/include/SDL_video.h b/include/SDL_video.h index bff95f81f..1ac2ebc56 100644 --- a/include/SDL_video.h +++ b/include/SDL_video.h @@ -483,24 +483,39 @@ extern DECLSPEC void SDLCALL SDL_SetWindowIcon(SDL_Window * window, SDL_Surface * icon); /** - * \brief Associate an arbitrary pointer with a window. + * \brief Associate an arbitrary named pointer with a window. * + * \param window The window to associate with the pointer. + * \param name The name of the pointer. + * \param userdata The associated pointer. + * + * \return The previous value associated with 'name' + * + * \note The name is case-sensitive. + * * \sa SDL_GetWindowData() */ -extern DECLSPEC void SDLCALL SDL_SetWindowData(SDL_Window * window, - void *userdata); +extern DECLSPEC void* SDLCALL SDL_SetWindowData(SDL_Window * window, + const char *name, + void *userdata); /** * \brief Retrieve the data pointer associated with a window. * + * \param window The window to query. + * \param name The name of the pointer. + * + * \return The value associated with 'name' + * * \sa SDL_SetWindowData() */ -extern DECLSPEC void *SDLCALL SDL_GetWindowData(SDL_Window * window); +extern DECLSPEC void *SDLCALL SDL_GetWindowData(SDL_Window * window, + const char *name); /** * \brief Set the position of a window. * - * \param window The window to reposition. + * \param window The window to reposition. * \param x The x coordinate of the window, ::SDL_WINDOWPOS_CENTERED, or ::SDL_WINDOWPOS_UNDEFINED. * \param y The y coordinate of the window, ::SDL_WINDOWPOS_CENTERED, or diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index d805f903b..75d5d9fcb 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -59,6 +59,13 @@ struct SDL_ShapeDriver int (*ResizeWindowShape)(SDL_Window *window); }; +typedef struct SDL_WindowUserData +{ + char *name; + void *data; + struct SDL_WindowUserData *next; +} SDL_WindowUserData; + /* Define the SDL window structure, corresponding to toplevel windows */ struct SDL_Window { @@ -75,7 +82,8 @@ struct SDL_Window SDL_WindowShaper *shaper; - void *userdata; + SDL_WindowUserData *data; + void *driverdata; SDL_Window *prev; diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 0793ae725..d4ec06e84 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -982,20 +982,60 @@ SDL_SetWindowIcon(SDL_Window * window, SDL_Surface * icon) } } -void -SDL_SetWindowData(SDL_Window * window, void *userdata) +void* +SDL_SetWindowData(SDL_Window * window, const char *name, void *userdata) { - CHECK_WINDOW_MAGIC(window, ); + SDL_WindowUserData *prev, *data; + + CHECK_WINDOW_MAGIC(window, NULL); + + /* See if the named data already exists */ + prev = NULL; + for (data = window->data; data; prev = data, data = data->next) { + if (SDL_strcmp(data->name, name) == 0) { + void *last_value = data->data; + + if (userdata) { + /* Set the new value */ + data->data = userdata; + } else { + /* Delete this value */ + if (prev) { + prev->next = data->next; + } else { + window->data = data->next; + } + SDL_free(data->name); + SDL_free(data); + } + return last_value; + } + } - window->userdata = userdata; + /* Add new data to the window */ + if (userdata) { + data = (SDL_WindowUserData *)SDL_malloc(sizeof(*data)); + data->name = SDL_strdup(name); + data->data = userdata; + data->next = window->data; + window->data = data; + } + return NULL; } void * -SDL_GetWindowData(SDL_Window * window) +SDL_GetWindowData(SDL_Window * window, const char *name) { + SDL_WindowUserData *data; + CHECK_WINDOW_MAGIC(window, NULL); - return window->userdata; + for (data = window->data; data; data = data->next) { + if (SDL_strcmp(data->name, name) == 0) { + return data->data; + } + } + return NULL; } void @@ -1293,10 +1333,6 @@ SDL_DestroyWindow(SDL_Window * window) CHECK_WINDOW_MAGIC(window, ); - if (window->title) { - SDL_free(window->title); - } - /* Restore video mode, etc. */ SDL_UpdateFullscreenMode(window, SDL_FALSE); @@ -1310,6 +1346,18 @@ SDL_DestroyWindow(SDL_Window * window) /* Now invalidate magic */ window->magic = NULL; + /* Free memory associated with the window */ + if (window->title) { + SDL_free(window->title); + } + while (window->data) { + SDL_WindowUserData *data = window->data; + + window->data = data->next; + SDL_free(data->name); + SDL_free(data); + } + /* Unlink the window from the list */ display = window->display; if (window->next) {