From 8c8ee2174d21637336eb5d3d21ec55b771a6caea Mon Sep 17 00:00:00 2001 From: Semphris Date: Wed, 22 May 2024 19:20:40 -0400 Subject: [PATCH] Dialog: Add filter number, remove NULL termination --- include/SDL3/SDL_dialog.h | 25 ++++++++-------- src/core/android/SDL_android.c | 13 +++------ src/core/android/SDL_android.h | 3 +- src/dialog/SDL_dialog_utils.c | 34 +++++++++++++--------- src/dialog/SDL_dialog_utils.h | 22 +++++++------- src/dialog/android/SDL_androiddialog.c | 8 +++--- src/dialog/cocoa/SDL_cocoadialog.m | 20 ++++++------- src/dialog/dummy/SDL_dummydialog.c | 4 +-- src/dialog/haiku/SDL_haikudialog.cc | 40 +++++++++++++------------- src/dialog/unix/SDL_portaldialog.c | 32 ++++++++++----------- src/dialog/unix/SDL_portaldialog.h | 4 +-- src/dialog/unix/SDL_unixdialog.c | 12 ++++---- src/dialog/unix/SDL_zenitydialog.c | 24 +++++++--------- src/dialog/unix/SDL_zenitydialog.h | 4 +-- src/dialog/windows/SDL_windowsdialog.c | 32 +++++++++------------ src/dynapi/SDL_dynapi_procs.h | 4 +-- test/testdialog.c | 10 +++---- 17 files changed, 144 insertions(+), 147 deletions(-) diff --git a/include/SDL3/SDL_dialog.h b/include/SDL3/SDL_dialog.h index 325af18c6f..286bf3c96f 100644 --- a/include/SDL3/SDL_dialog.h +++ b/include/SDL3/SDL_dialog.h @@ -78,10 +78,9 @@ typedef struct SDL_DialogFileFilter * The filelist argument does not need to be freed; it will automatically be * freed when the callback returns. * - * The filter argument is the index of the filter that was selected, or one - * more than the size of the list (therefore the index of the terminating NULL - * entry) if no filter was selected, or -1 if the platform or method doesn't - * support fetching the selected filter. + * The filter argument is the index of the filter that was selected, or -1 if + * no filter was selected or if the platform or method doesn't support fetching + * the selected filter. * * \param userdata An app-provided pointer, for the callback's use. * \param filelist The file(s) chosen by the user. @@ -135,9 +134,10 @@ typedef void(SDLCALL *SDL_DialogFileCallback)(void *userdata, const char * const * it will be invoked. * \param window The window that the dialog should be modal for. May be NULL. * Not all platforms support this option. - * \param filters A null-terminated list of SDL_DialogFileFilter's. May be - * NULL. Not all platforms support this option, and platforms - * that do support it may allow the user to ignore the filters. + * \param filters A list of SDL_DialogFileFilter's. May be NULL. Not all + * platforms support this option, and platforms that do support + * it may allow the user to ignore the filters. + * \param nfilters The number of filters. Ignored if filters is NULL. * \param default_location The default folder or file to start the dialog at. * May be NULL. Not all platforms support this option. * \param allow_many If non-zero, the user will be allowed to select multiple @@ -150,7 +150,7 @@ typedef void(SDLCALL *SDL_DialogFileCallback)(void *userdata, const char * const * \sa SDL_ShowSaveFileDialog * \sa SDL_ShowOpenFolderDialog */ -extern SDL_DECLSPEC void SDLCALL SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, const char *default_location, SDL_bool allow_many); +extern SDL_DECLSPEC void SDLCALL SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, int nfilters, const char *default_location, SDL_bool allow_many); /** * Displays a dialog that lets the user choose a new or existing file on their @@ -191,9 +191,10 @@ extern SDL_DECLSPEC void SDLCALL SDL_ShowOpenFileDialog(SDL_DialogFileCallback c * it will be invoked. * \param window The window that the dialog should be modal for. May be NULL. * Not all platforms support this option. - * \param filters A null-terminated list of SDL_DialogFileFilter's. May be - * NULL. Not all platforms support this option, and platforms - * that do support it may allow the user to ignore the filters. + * \param filters A list of SDL_DialogFileFilter's. May be NULL. Not all + * platforms support this option, and platforms that do support + * it may allow the user to ignore the filters. + * \param nfilters The number of filters. Ignored if filters is NULL. * \param default_location The default folder or file to start the dialog at. * May be NULL. Not all platforms support this option. * @@ -204,7 +205,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_ShowOpenFileDialog(SDL_DialogFileCallback c * \sa SDL_ShowOpenFileDialog * \sa SDL_ShowOpenFolderDialog */ -extern SDL_DECLSPEC void SDLCALL SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, const char *default_location); +extern SDL_DECLSPEC void SDLCALL SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, int nfilters, const char *default_location); /** * Displays a dialog that lets the user select a folder on their filesystem. diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index cce8e7a535..484aec94f1 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -2910,7 +2910,8 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeFileDialog)( SDL_bool Android_JNI_OpenFileDialog( SDL_DialogFileCallback callback, void* userdata, - const SDL_DialogFileFilter *filters, SDL_bool forwrite, SDL_bool multiple) + const SDL_DialogFileFilter *filters, int nfilters, SDL_bool forwrite, + SDL_bool multiple) { if (mAndroidFileDialogData.callback != NULL) { SDL_SetError("Only one file dialog can be run at a time."); @@ -2926,17 +2927,11 @@ SDL_bool Android_JNI_OpenFileDialog( /* Setup filters */ jobjectArray filtersArray = NULL; if (filters) { - /* Count how many filters */ - int count = 0; - for (const SDL_DialogFileFilter *f = filters; f->name != NULL && f->pattern != NULL; f++) { - count++; - } - jclass stringClass = (*env)->FindClass(env, "java/lang/String"); - filtersArray = (*env)->NewObjectArray(env, count, stringClass, NULL); + filtersArray = (*env)->NewObjectArray(env, nfilters, stringClass, NULL); /* Convert to string */ - for (int i = 0; i < count; i++) { + for (int i = 0; i < nfilters; i++) { jstring str = (*env)->NewStringUTF(env, filters[i].pattern); (*env)->SetObjectArrayElement(env, filtersArray, i, str); (*env)->DeleteLocalRef(env, str); diff --git a/src/core/android/SDL_android.h b/src/core/android/SDL_android.h index db56846b73..71704203ed 100644 --- a/src/core/android/SDL_android.h +++ b/src/core/android/SDL_android.h @@ -144,7 +144,8 @@ void Android_ActivityMutex_Lock_Running(void); /* File Dialogs */ SDL_bool Android_JNI_OpenFileDialog(SDL_DialogFileCallback callback, void* userdata, - const SDL_DialogFileFilter *filters, SDL_bool forwrite, SDL_bool multiple); + const SDL_DialogFileFilter *filters, int nfilters, SDL_bool forwrite, + SDL_bool multiple); /* Ends C function definitions when using C++ */ #ifdef __cplusplus diff --git a/src/dialog/SDL_dialog_utils.c b/src/dialog/SDL_dialog_utils.c index 030c15e5b7..d961553570 100644 --- a/src/dialog/SDL_dialog_utils.c +++ b/src/dialog/SDL_dialog_utils.c @@ -22,18 +22,24 @@ #include "SDL_dialog_utils.h" -char *convert_filters(const SDL_DialogFileFilter *filters, NameTransform ntf, - const char *prefix, const char *separator, - const char *suffix, const char *filt_prefix, - const char *filt_separator, const char *filt_suffix, - const char *ext_prefix, const char *ext_separator, - const char *ext_suffix) +char *convert_filters(const SDL_DialogFileFilter *filters, int nfilters, + NameTransform ntf, const char *prefix, + const char *separator, const char *suffix, + const char *filt_prefix, const char *filt_separator, + const char *filt_suffix, const char *ext_prefix, + const char *ext_separator, const char *ext_suffix) { char *combined; char *new_combined; char *converted; const char *terminator; size_t new_length; + int i; + + if (!filters) { + SDL_SetError("Called convert_filters() with NULL filters (SDL bug)"); + return NULL; + } combined = SDL_strdup(prefix); @@ -41,7 +47,9 @@ char *convert_filters(const SDL_DialogFileFilter *filters, NameTransform ntf, return NULL; } - for (const SDL_DialogFileFilter *f = filters; f->name && f->pattern; f++) { + for (i = 0; i < nfilters; i++) { + const SDL_DialogFileFilter *f = &filters[i]; + converted = convert_filter(*f, ntf, filt_prefix, filt_separator, filt_suffix, ext_prefix, ext_separator, ext_suffix); @@ -90,9 +98,9 @@ char *convert_filters(const SDL_DialogFileFilter *filters, NameTransform ntf, } char *convert_filter(const SDL_DialogFileFilter filter, NameTransform ntf, - const char *prefix, const char *separator, - const char *suffix, const char *ext_prefix, - const char *ext_separator, const char *ext_suffix) + const char *prefix, const char *separator, + const char *suffix, const char *ext_prefix, + const char *ext_separator, const char *ext_suffix) { char *converted; char *name_filtered; @@ -208,11 +216,11 @@ char *convert_ext_list(const char *list, const char *prefix, return converted; } -const char *validate_filters(const SDL_DialogFileFilter *filters) +const char *validate_filters(const SDL_DialogFileFilter *filters, int nfilters) { if (filters) { - for (const SDL_DialogFileFilter *f = filters; f->name && f->pattern; f++) { - const char *msg = validate_list(f->pattern); + for (int i = 0; i < nfilters; i++) { + const char *msg = validate_list(filters[i].pattern); if (msg) { return msg; diff --git a/src/dialog/SDL_dialog_utils.h b/src/dialog/SDL_dialog_utils.h index 8f4a49bf05..26d178e4d6 100644 --- a/src/dialog/SDL_dialog_utils.h +++ b/src/dialog/SDL_dialog_utils.h @@ -32,19 +32,19 @@ typedef char *(NameTransform)(const char * name); /* Converts all the filters into a single string. */ /* [filter]{[filter]...} */ -char *convert_filters(const SDL_DialogFileFilter *filters, NameTransform ntf, - const char *prefix, const char *separator, - const char *suffix, const char *filt_prefix, - const char *filt_separator, const char *filt_suffix, - const char *ext_prefix, const char *ext_separator, - const char *ext_suffix); +char *convert_filters(const SDL_DialogFileFilter *filters, int nfilters, + NameTransform ntf, const char *prefix, + const char *separator, const char *suffix, + const char *filt_prefix, const char *filt_separator, + const char *filt_suffix, const char *ext_prefix, + const char *ext_separator, const char *ext_suffix); /* Converts one filter into a single string. */ /* [filter name][filter extension list] */ char *convert_filter(const SDL_DialogFileFilter filter, NameTransform ntf, - const char *prefix, const char *separator, - const char *suffix, const char *ext_prefix, - const char *ext_separator, const char *ext_suffix); + const char *prefix, const char *separator, + const char *suffix, const char *ext_prefix, + const char *ext_separator, const char *ext_suffix); /* Converts the extenstion list of a filter into a single string. */ /* [extension]{[extension]...} */ @@ -53,5 +53,7 @@ char *convert_ext_list(const char *list, const char *prefix, /* Must be used if convert_* functions aren't used */ /* Returns an error message if there's a problem, NULL otherwise */ -const char *validate_filters(const SDL_DialogFileFilter *filters); +const char *validate_filters(const SDL_DialogFileFilter *filters, + int nfilters); + const char *validate_list(const char *list); diff --git a/src/dialog/android/SDL_androiddialog.c b/src/dialog/android/SDL_androiddialog.c index c6418f162b..19b212e2ce 100644 --- a/src/dialog/android/SDL_androiddialog.c +++ b/src/dialog/android/SDL_androiddialog.c @@ -22,17 +22,17 @@ #include "SDL_internal.h" #include "../../core/android/SDL_android.h" -void SDLCALL SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, const char *default_location, SDL_bool allow_many) +void SDLCALL SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, int nfilters, const char *default_location, SDL_bool allow_many) { - if (!Android_JNI_OpenFileDialog(callback, userdata, filters, SDL_FALSE, allow_many)) { + if (!Android_JNI_OpenFileDialog(callback, userdata, filters, nfilters, SDL_FALSE, allow_many)) { /* SDL_SetError is already called when it fails */ callback(userdata, NULL, -1); } } -void SDLCALL SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, const char *default_location) +void SDLCALL SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, int nfilters, const char *default_location) { - if (!Android_JNI_OpenFileDialog(callback, userdata, filters, SDL_TRUE, SDL_FALSE)) { + if (!Android_JNI_OpenFileDialog(callback, userdata, filters, nfilters, SDL_TRUE, SDL_FALSE)) { /* SDL_SetError is already called when it fails */ callback(userdata, NULL, -1); } diff --git a/src/dialog/cocoa/SDL_cocoadialog.m b/src/dialog/cocoa/SDL_cocoadialog.m index b464e39889..3d58aa226c 100644 --- a/src/dialog/cocoa/SDL_cocoadialog.m +++ b/src/dialog/cocoa/SDL_cocoadialog.m @@ -31,14 +31,14 @@ typedef enum FDT_OPENFOLDER } cocoa_FileDialogType; -void show_file_dialog(cocoa_FileDialogType type, SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many) +void show_file_dialog(cocoa_FileDialogType type, SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, SDL_bool allow_many) { #if defined(SDL_PLATFORM_TVOS) || defined(SDL_PLATFORM_IOS) SDL_SetError("tvOS and iOS don't support path-based file dialogs"); callback(userdata, NULL, -1); #else if (filters) { - const char *msg = validate_filters(filters); + const char *msg = validate_filters(filters, nfilters); if (msg) { SDL_SetError("%s", msg); @@ -76,13 +76,11 @@ void show_file_dialog(cocoa_FileDialogType type, SDL_DialogFileCallback callback }; if (filters) { - int n = -1; - while (filters[++n].name && filters[n].pattern); // On macOS 11.0 and up, this is an array of UTType. Prior to that, it's an array of NSString - NSMutableArray *types = [[NSMutableArray alloc] initWithCapacity:n ]; + NSMutableArray *types = [[NSMutableArray alloc] initWithCapacity:nfilters ]; int has_all_files = 0; - for (int i = 0; i < n; i++) { + for (int i = 0; i < nfilters; i++) { char *pattern = SDL_strdup(filters[i].pattern); char *pattern_ptr = pattern; @@ -180,17 +178,17 @@ void show_file_dialog(cocoa_FileDialogType type, SDL_DialogFileCallback callback #endif // defined(SDL_PLATFORM_TVOS) || defined(SDL_PLATFORM_IOS) } -void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many) +void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, SDL_bool allow_many) { - show_file_dialog(FDT_OPEN, callback, userdata, window, filters, default_location, allow_many); + show_file_dialog(FDT_OPEN, callback, userdata, window, filters, nfilters, default_location, allow_many); } -void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location) +void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location) { - show_file_dialog(FDT_SAVE, callback, userdata, window, filters, default_location, 0); + show_file_dialog(FDT_SAVE, callback, userdata, window, filters, nfilters, default_location, 0); } void SDL_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const char* default_location, SDL_bool allow_many) { - show_file_dialog(FDT_OPENFOLDER, callback, userdata, window, NULL, default_location, allow_many); + show_file_dialog(FDT_OPENFOLDER, callback, userdata, window, NULL, 0, default_location, allow_many); } diff --git a/src/dialog/dummy/SDL_dummydialog.c b/src/dialog/dummy/SDL_dummydialog.c index 057bb67d8b..0f7456b90c 100644 --- a/src/dialog/dummy/SDL_dummydialog.c +++ b/src/dialog/dummy/SDL_dummydialog.c @@ -20,13 +20,13 @@ */ #include "SDL_internal.h" -void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many) +void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, SDL_bool allow_many) { SDL_Unsupported(); callback(userdata, NULL, -1); } -void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location) +void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location) { SDL_Unsupported(); callback(userdata, NULL, -1); diff --git a/src/dialog/haiku/SDL_haikudialog.cc b/src/dialog/haiku/SDL_haikudialog.cc index ac28415c61..9c03958610 100644 --- a/src/dialog/haiku/SDL_haikudialog.cc +++ b/src/dialog/haiku/SDL_haikudialog.cc @@ -60,9 +60,10 @@ std::vector StringSplit(const std::string& str, const std::string& class SDLBRefFilter : public BRefFilter { public: - SDLBRefFilter(const SDL_DialogFileFilter *filters) : + SDLBRefFilter(const SDL_DialogFileFilter *filters, int nfilters) : BRefFilter(), - m_filters(filters) + m_filters(filters), + m_nfilters(nfilters) { } @@ -81,14 +82,12 @@ public: if (S_ISDIR(info.st_mode)) return true; - const auto *filter = m_filters; - while (filter->name && filter->pattern) { - for (const auto& suffix : StringSplit(filter->pattern, ";")) { + for (int i = 0; i < m_nfilters; i++) { + for (const auto& suffix : StringSplit(m_filters[i].pattern, ";")) { if (StringEndsWith(result, std::string(".") + suffix)) { return true; } } - filter++; } return false; @@ -96,6 +95,7 @@ public: private: const SDL_DialogFileFilter * const m_filters; + int m_nfilters; }; class CallbackLooper : public BLooper @@ -190,7 +190,7 @@ private: SDLBRefFilter *m_filter; }; -void ShowDialog(bool save, SDL_DialogFileCallback callback, void *userdata, bool many, bool modal, const SDL_DialogFileFilter *filters, bool folder, const char *location) +void ShowDialog(bool save, SDL_DialogFileCallback callback, void *userdata, bool many, bool modal, const SDL_DialogFileFilter *filters, int nfilters, bool folder, const char *location) { if (SDL_InitBeApp()) { char* err = SDL_strdup(SDL_GetError()); @@ -200,12 +200,14 @@ void ShowDialog(bool save, SDL_DialogFileCallback callback, void *userdata, bool return; } - const char *msg = validate_filters(filters); + if (filters) { + const char *msg = validate_filters(filters, nfilters); - if (msg) { - SDL_SetError("%s", msg); - callback(userdata, NULL, -1); - return; + if (msg) { + SDL_SetError("%s", msg); + callback(userdata, NULL, -1); + return; + } } if (SDL_GetHint(SDL_HINT_FILE_DIALOG_DRIVER) != NULL) { @@ -217,7 +219,7 @@ void ShowDialog(bool save, SDL_DialogFileCallback callback, void *userdata, bool // No unique_ptr's because they need to survive the end of the function CallbackLooper *looper = new(std::nothrow) CallbackLooper(callback, userdata); BMessenger *messenger = new(std::nothrow) BMessenger(NULL, looper); - SDLBRefFilter *filter = new(std::nothrow) SDLBRefFilter(filters); + SDLBRefFilter *filter = new(std::nothrow) SDLBRefFilter(filters, nfilters); if (looper == NULL || messenger == NULL || filter == NULL) { SDL_free(looper); @@ -241,19 +243,17 @@ void ShowDialog(bool save, SDL_DialogFileCallback callback, void *userdata, bool panel->Show(); } -void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, const char *default_location, SDL_bool allow_many) +void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, int nfilters, const char *default_location, SDL_bool allow_many) { - ShowDialog(false, callback, userdata, allow_many == SDL_TRUE, !!window, filters, false, default_location); + ShowDialog(false, callback, userdata, allow_many == SDL_TRUE, !!window, filters, nfilters, false, default_location); } -void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, const char *default_location) +void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, int nfilters, const char *default_location) { - ShowDialog(true, callback, userdata, false, !!window, filters, false, default_location); + ShowDialog(true, callback, userdata, false, !!window, filters, nfilters, false, default_location); } void SDL_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const char* default_location, SDL_bool allow_many) { - // Use a dummy filter to avoid showing files in the dialog - SDL_DialogFileFilter filter[] = {{}}; - ShowDialog(false, callback, userdata, allow_many == SDL_TRUE, !!window, filter, true, default_location); + ShowDialog(false, callback, userdata, allow_many == SDL_TRUE, !!window, NULL, 0, true, default_location); } diff --git a/src/dialog/unix/SDL_portaldialog.c b/src/dialog/unix/SDL_portaldialog.c index 8aa55bfde2..d9717750b8 100644 --- a/src/dialog/unix/SDL_portaldialog.c +++ b/src/dialog/unix/SDL_portaldialog.c @@ -74,17 +74,17 @@ static void DBus_AppendBoolOption(SDL_DBusContext *dbus, DBusMessageIter *option dbus->message_iter_close_container(options, &options_pair); } -static void DBus_AppendFilter(SDL_DBusContext *dbus, DBusMessageIter *parent, const SDL_DialogFileFilter *filter) +static void DBus_AppendFilter(SDL_DBusContext *dbus, DBusMessageIter *parent, const SDL_DialogFileFilter filter) { DBusMessageIter filter_entry, filter_array, filter_array_entry; char *state = NULL, *patterns, *pattern, *glob_pattern; int zero = 0; dbus->message_iter_open_container(parent, DBUS_TYPE_STRUCT, NULL, &filter_entry); - dbus->message_iter_append_basic(&filter_entry, DBUS_TYPE_STRING, &filter->name); + dbus->message_iter_append_basic(&filter_entry, DBUS_TYPE_STRING, &filter.name); dbus->message_iter_open_container(&filter_entry, DBUS_TYPE_ARRAY, "(us)", &filter_array); - patterns = SDL_strdup(filter->pattern); + patterns = SDL_strdup(filter.pattern); if (!patterns) { goto cleanup; } @@ -120,7 +120,7 @@ cleanup: dbus->message_iter_close_container(parent, &filter_entry); } -static void DBus_AppendFilters(SDL_DBusContext *dbus, DBusMessageIter *options, const SDL_DialogFileFilter *filters) +static void DBus_AppendFilters(SDL_DBusContext *dbus, DBusMessageIter *options, const SDL_DialogFileFilter *filters, int nfilters) { DBusMessageIter options_pair, options_value, options_value_array; static const char *filters_name = "filters"; @@ -129,8 +129,8 @@ static void DBus_AppendFilters(SDL_DBusContext *dbus, DBusMessageIter *options, dbus->message_iter_append_basic(&options_pair, DBUS_TYPE_STRING, &filters_name); dbus->message_iter_open_container(&options_pair, DBUS_TYPE_VARIANT, "a(sa(us))", &options_value); dbus->message_iter_open_container(&options_value, DBUS_TYPE_ARRAY, "(sa(us))", &options_value_array); - for (const SDL_DialogFileFilter *filter = filters; filter && filter->name && filter->pattern; ++filter) { - DBus_AppendFilter(dbus, &options_value_array, filter); + for (int i = 0; i < nfilters; i++) { + DBus_AppendFilter(dbus, &options_value_array, filters[i]); } dbus->message_iter_close_container(&options_value, &options_value_array); dbus->message_iter_close_container(&options_pair, &options_value); @@ -269,7 +269,7 @@ not_our_signal: return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -static void DBus_OpenDialog(const char *method, const char *method_title, SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many, int open_folders) +static void DBus_OpenDialog(const char *method, const char *method_title, SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, SDL_bool allow_many, int open_folders) { SDL_DBusContext *dbus = SDL_DBus_GetContext(); DBusMessage *msg; @@ -281,7 +281,7 @@ static void DBus_OpenDialog(const char *method, const char *method_title, SDL_Di static char *default_parent_window = ""; SDL_PropertiesID props = SDL_GetWindowProperties(window); - const char *err_msg = validate_filters(filters); + const char *err_msg = validate_filters(filters, nfilters); if (err_msg) { SDL_SetError("%s", err_msg); @@ -358,7 +358,7 @@ static void DBus_OpenDialog(const char *method, const char *method_title, SDL_Di DBus_AppendBoolOption(dbus, &options, "directory", 1); } if (filters) { - DBus_AppendFilters(dbus, &options, filters); + DBus_AppendFilters(dbus, &options, filters, nfilters); } if (default_location) { DBus_AppendByteArray(dbus, &options, "current_folder", default_location); @@ -419,19 +419,19 @@ incorrect_type: dbus->message_unref(reply); } -void SDL_Portal_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many) +void SDL_Portal_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, SDL_bool allow_many) { - DBus_OpenDialog("OpenFile", "Open File", callback, userdata, window, filters, default_location, allow_many, 0); + DBus_OpenDialog("OpenFile", "Open File", callback, userdata, window, filters, nfilters, default_location, allow_many, 0); } -void SDL_Portal_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location) +void SDL_Portal_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location) { - DBus_OpenDialog("SaveFile", "Save File", callback, userdata, window, filters, default_location, 0, 0); + DBus_OpenDialog("SaveFile", "Save File", callback, userdata, window, filters, nfilters, default_location, 0, 0); } void SDL_Portal_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const char* default_location, SDL_bool allow_many) { - DBus_OpenDialog("OpenFile", "Open Folder", callback, userdata, window, NULL, default_location, allow_many, 1); + DBus_OpenDialog("OpenFile", "Open Folder", callback, userdata, window, NULL, 0, default_location, allow_many, 1); } int SDL_Portal_detect(void) @@ -494,13 +494,13 @@ done: /* Dummy implementation to avoid compilation problems */ -void SDL_Portal_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many) +void SDL_Portal_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, SDL_bool allow_many) { SDL_Unsupported(); callback(userdata, NULL, -1); } -void SDL_Portal_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location) +void SDL_Portal_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location) { SDL_Unsupported(); callback(userdata, NULL, -1); diff --git a/src/dialog/unix/SDL_portaldialog.h b/src/dialog/unix/SDL_portaldialog.h index 71ed3cbedf..f0051d3033 100644 --- a/src/dialog/unix/SDL_portaldialog.h +++ b/src/dialog/unix/SDL_portaldialog.h @@ -21,8 +21,8 @@ #include "SDL_internal.h" -void SDL_Portal_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many); -void SDL_Portal_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location); +void SDL_Portal_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, SDL_bool allow_many); +void SDL_Portal_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location); void SDL_Portal_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const char* default_location, SDL_bool allow_many); /** @returns non-zero if available, zero if unavailable */ diff --git a/src/dialog/unix/SDL_unixdialog.c b/src/dialog/unix/SDL_unixdialog.c index ae57833fe8..d489094a57 100644 --- a/src/dialog/unix/SDL_unixdialog.c +++ b/src/dialog/unix/SDL_unixdialog.c @@ -23,8 +23,8 @@ #include "./SDL_portaldialog.h" #include "./SDL_zenitydialog.h" -static void (*detected_open)(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many) = NULL; -static void (*detected_save)(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location) = NULL; +static void (*detected_open)(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, SDL_bool allow_many) = NULL; +static void (*detected_save)(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location) = NULL; static void (*detected_folder)(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const char* default_location, SDL_bool allow_many) = NULL; static int detect_available_methods(const char *value); @@ -73,7 +73,7 @@ static int detect_available_methods(const char *value) return 0; } -void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many) +void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, SDL_bool allow_many) { /* Call detect_available_methods() again each time in case the situation changed */ if (!detected_open && !detect_available_methods(NULL)) { @@ -82,10 +82,10 @@ void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL return; } - detected_open(callback, userdata, window, filters, default_location, allow_many); + detected_open(callback, userdata, window, filters, nfilters, default_location, allow_many); } -void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location) +void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location) { /* Call detect_available_methods() again each time in case the situation changed */ if (!detected_save && !detect_available_methods(NULL)) { @@ -94,7 +94,7 @@ void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL return; } - detected_save(callback, userdata, window, filters, default_location); + detected_save(callback, userdata, window, filters, nfilters, default_location); } void SDL_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const char* default_location, SDL_bool allow_many) diff --git a/src/dialog/unix/SDL_zenitydialog.c b/src/dialog/unix/SDL_zenitydialog.c index 66faeaad62..929415195f 100644 --- a/src/dialog/unix/SDL_zenitydialog.c +++ b/src/dialog/unix/SDL_zenitydialog.c @@ -39,6 +39,7 @@ typedef struct void* userdata; const char* filename; const SDL_DialogFileFilter *filters; + int nfilters; Uint32 flags; } zenityArgs; @@ -110,12 +111,7 @@ static char** generate_args(const zenityArgs* info) } if (info->filters) { - const SDL_DialogFileFilter *filter_ptr = info->filters; - - while (filter_ptr->name && filter_ptr->pattern) { - argc++; - filter_ptr++; - } + argc += info->nfilters; } argv = SDL_malloc(sizeof(char *) * argc + 1); @@ -157,10 +153,9 @@ static char** generate_args(const zenityArgs* info) } if (info->filters) { - const SDL_DialogFileFilter *filter_ptr = info->filters; - - while (filter_ptr->name && filter_ptr->pattern) { - char *filter_str = convert_filter(*filter_ptr, zenity_clean_name, + for (int i = 0; i < info->nfilters; i++) { + char *filter_str = convert_filter(info->filters[i], + zenity_clean_name, "--file-filter=", " | ", "", "*.", " *.", ""); @@ -170,8 +165,6 @@ static char** generate_args(const zenityArgs* info) argv[nextarg++] = filter_str; CHECK_OOM() - - filter_ptr++; } } @@ -330,7 +323,7 @@ static int run_zenity_thread(void* ptr) return 0; } -void SDL_Zenity_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many) +void SDL_Zenity_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, SDL_bool allow_many) { zenityArgs *args; SDL_Thread *thread; @@ -345,6 +338,7 @@ void SDL_Zenity_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userda args->userdata = userdata; args->filename = default_location; args->filters = filters; + args->nfilters = nfilters; args->flags = (allow_many == SDL_TRUE) ? ZENITY_MULTIPLE : 0; thread = SDL_CreateThread(run_zenity_thread, "SDL_ShowOpenFileDialog", (void *) args); @@ -357,7 +351,7 @@ void SDL_Zenity_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userda SDL_DetachThread(thread); } -void SDL_Zenity_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location) +void SDL_Zenity_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location) { zenityArgs *args; SDL_Thread *thread; @@ -372,6 +366,7 @@ void SDL_Zenity_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userda args->userdata = userdata; args->filename = default_location; args->filters = filters; + args->nfilters = nfilters; args->flags = ZENITY_SAVE; thread = SDL_CreateThread(run_zenity_thread, "SDL_ShowSaveFileDialog", (void *) args); @@ -399,6 +394,7 @@ void SDL_Zenity_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void* user args->userdata = userdata; args->filename = default_location; args->filters = NULL; + args->nfilters = 0; args->flags = ((allow_many == SDL_TRUE) ? ZENITY_MULTIPLE : 0) | ZENITY_DIRECTORY; thread = SDL_CreateThread(run_zenity_thread, "SDL_ShowOpenFolderDialog", (void *) args); diff --git a/src/dialog/unix/SDL_zenitydialog.h b/src/dialog/unix/SDL_zenitydialog.h index 9d7203b67f..3c200639a2 100644 --- a/src/dialog/unix/SDL_zenitydialog.h +++ b/src/dialog/unix/SDL_zenitydialog.h @@ -21,8 +21,8 @@ #include "SDL_internal.h" -void SDL_Zenity_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many); -void SDL_Zenity_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location); +void SDL_Zenity_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, SDL_bool allow_many); +void SDL_Zenity_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location); void SDL_Zenity_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const char* default_location, SDL_bool allow_many); /** @returns non-zero if available, zero if unavailable */ diff --git a/src/dialog/windows/SDL_windowsdialog.c b/src/dialog/windows/SDL_windowsdialog.c index d749c711bf..45bc6418c6 100644 --- a/src/dialog/windows/SDL_windowsdialog.c +++ b/src/dialog/windows/SDL_windowsdialog.c @@ -34,6 +34,7 @@ typedef struct { int is_save; const SDL_DialogFileFilter *filters; + int nfilters; const char* default_file; SDL_Window* parent; DWORD flags; @@ -50,18 +51,9 @@ typedef struct } winFArgs; /** Converts dialog.nFilterIndex to SDL-compatible value */ -int getFilterIndex(int as_reported_by_windows, const SDL_DialogFileFilter *filters) +int getFilterIndex(int as_reported_by_windows) { - int filter_index = as_reported_by_windows - 1; - - if (filter_index < 0) { - filter_index = 0; - for (const SDL_DialogFileFilter *filter = filters; filter && filter->name && filter->pattern; filter++) { - filter_index++; - } - } - - return filter_index; + return as_reported_by_windows - 1; } /* TODO: The new version of file dialogs */ @@ -70,6 +62,7 @@ void windows_ShowFileDialog(void *ptr) winArgs *args = (winArgs *) ptr; int is_save = args->is_save; const SDL_DialogFileFilter *filters = args->filters; + int nfilters = args->nfilters; const char* default_file = args->default_file; SDL_Window* parent = args->parent; DWORD flags = args->flags; @@ -160,8 +153,9 @@ void windows_ShowFileDialog(void *ptr) if (filters) { /* '\x01' is used in place of a null byte */ /* suffix needs two null bytes in case the filter list is empty */ - char *filterlist = convert_filters(filters, NULL, "", "", "\x01\x01", "", - "\x01", "\x01", "*.", ";*.", ""); + char *filterlist = convert_filters(filters, nfilters, NULL, "", "", + "\x01\x01", "", "\x01", "\x01", + "*.", ";*.", ""); if (!filterlist) { callback(userdata, NULL, -1); @@ -224,7 +218,7 @@ void windows_ShowFileDialog(void *ptr) /* File is a C string stored in dialog.lpstrFile */ char *chosen_file = WIN_StringToUTF8W(dialog.lpstrFile); const char* opts[2] = { chosen_file, NULL }; - callback(userdata, opts, getFilterIndex(dialog.nFilterIndex, filters)); + callback(userdata, opts, getFilterIndex(dialog.nFilterIndex)); SDL_free(chosen_file); } else { /* File is either a C string if the user chose a single file, else @@ -336,7 +330,7 @@ void windows_ShowFileDialog(void *ptr) } } - callback(userdata, (const char * const*) chosen_files_list, getFilterIndex(dialog.nFilterIndex, filters)); + callback(userdata, (const char * const*) chosen_files_list, getFilterIndex(dialog.nFilterIndex)); for (size_t i = 0; i < nfiles; i++) { SDL_free(chosen_files_list[i]); @@ -353,7 +347,7 @@ void windows_ShowFileDialog(void *ptr) function before set a different error code, so it's safe to check for success. */ const char* opts[1] = { NULL }; - callback(userdata, opts, getFilterIndex(dialog.nFilterIndex, filters)); + callback(userdata, opts, getFilterIndex(dialog.nFilterIndex)); } else { SDL_SetError("Windows error, CommDlgExtendedError: %ld", pCommDlgExtendedError()); callback(userdata, NULL, -1); @@ -433,7 +427,7 @@ int windows_folder_dialog_thread(void* ptr) return 0; } -void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many) +void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location, SDL_bool allow_many) { winArgs *args; SDL_Thread *thread; @@ -453,6 +447,7 @@ void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL args->is_save = 0; args->filters = filters; + args->nfilters = nfilters; args->default_file = default_location; args->parent = window; args->flags = (allow_many == SDL_TRUE) ? OFN_ALLOWMULTISELECT : 0; @@ -470,7 +465,7 @@ void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL SDL_DetachThread(thread); } -void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location) +void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, int nfilters, const char* default_location) { winArgs *args; SDL_Thread *thread; @@ -489,6 +484,7 @@ void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL args->is_save = 1; args->filters = filters; + args->nfilters = nfilters; args->default_file = default_location; args->parent = window; args->flags = 0; diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 43983a5112..1a68733e3e 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -810,9 +810,9 @@ SDL_DYNAPI_PROC(void,SDL_SetWindowsMessageHook,(SDL_WindowsMessageHook a, void * SDL_DYNAPI_PROC(void,SDL_SetX11EventHook,(SDL_X11EventHook a, void *b),(a,b),) SDL_DYNAPI_PROC(int,SDL_ShowCursor,(void),(),return) SDL_DYNAPI_PROC(int,SDL_ShowMessageBox,(const SDL_MessageBoxData *a, int *b),(a,b),return) -SDL_DYNAPI_PROC(void,SDL_ShowOpenFileDialog,(SDL_DialogFileCallback a, void *b, SDL_Window *c, const SDL_DialogFileFilter *d, const char *e, SDL_bool f),(a,b,c,d,e,f),) +SDL_DYNAPI_PROC(void,SDL_ShowOpenFileDialog,(SDL_DialogFileCallback a, void *b, SDL_Window *c, const SDL_DialogFileFilter *d, int e, const char *f, SDL_bool g),(a,b,c,d,e,f,g),) SDL_DYNAPI_PROC(void,SDL_ShowOpenFolderDialog,(SDL_DialogFileCallback a, void *b, SDL_Window *c, const char *d, SDL_bool e),(a,b,c,d,e),) -SDL_DYNAPI_PROC(void,SDL_ShowSaveFileDialog,(SDL_DialogFileCallback a, void *b, SDL_Window *c, const SDL_DialogFileFilter *d, const char *e),(a,b,c,d,e),) +SDL_DYNAPI_PROC(void,SDL_ShowSaveFileDialog,(SDL_DialogFileCallback a, void *b, SDL_Window *c, const SDL_DialogFileFilter *d, int e, const char *f),(a,b,c,d,e,f),) SDL_DYNAPI_PROC(int,SDL_ShowSimpleMessageBox,(SDL_MessageBoxFlags a, const char *b, const char *c, SDL_Window *d),(a,b,c,d),return) SDL_DYNAPI_PROC(int,SDL_ShowWindow,(SDL_Window *a),(a),return) SDL_DYNAPI_PROC(int,SDL_ShowWindowSystemMenu,(SDL_Window *a, int b, int c),(a,b,c),return) diff --git a/test/testdialog.c b/test/testdialog.c index d5e9365424..eff2525524 100644 --- a/test/testdialog.c +++ b/test/testdialog.c @@ -15,11 +15,10 @@ #include #include -const SDL_DialogFileFilter filters[4] = { +const SDL_DialogFileFilter filters[3] = { { "All files", "*" }, { "JPG images", "jpg;jpeg" }, - { "PNG images", "png" }, - { NULL, NULL } + { "PNG images", "png" } }; static void SDLCALL callback(void* userdata, const char* const* files, int filter) { @@ -54,6 +53,7 @@ int main(int argc, char *argv[]) { const SDL_FRect open_folder_rect = { 370, 50, 220, 140 }; int i; char *initial_path = NULL; + const int nfilters = sizeof(filters) / sizeof(*filters); /* Initialize test framework */ state = SDLTest_CommonCreateState(argv, 0); @@ -114,11 +114,11 @@ int main(int argc, char *argv[]) { * - Nonzero if the user is allowed to choose multiple entries (not for SDL_ShowSaveFileDialog) */ if (SDL_PointInRectFloat(&p, &open_file_rect)) { - SDL_ShowOpenFileDialog(callback, NULL, w, filters, initial_path, 1); + SDL_ShowOpenFileDialog(callback, NULL, w, filters, nfilters, initial_path, 1); } else if (SDL_PointInRectFloat(&p, &open_folder_rect)) { SDL_ShowOpenFolderDialog(callback, NULL, w, initial_path, 1); } else if (SDL_PointInRectFloat(&p, &save_file_rect)) { - SDL_ShowSaveFileDialog(callback, NULL, w, filters, initial_path); + SDL_ShowSaveFileDialog(callback, NULL, w, filters, nfilters, initial_path); } } }