Skip to content

Commit

Permalink
Add versioned API
Browse files Browse the repository at this point in the history
  • Loading branch information
btzy committed Mar 31, 2024
1 parent 17b6e8c commit 552d463
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 24 deletions.
74 changes: 74 additions & 0 deletions src/include/nfd.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,28 @@ typedef struct {
typedef nfdu8filteritem_t nfdnfilteritem_t;
#endif // _WIN32

typedef size_t nfdversion_t;

typedef struct {
const nfdu8filteritem_t* filterList;
nfdfiltersize_t filterCount;
const nfdu8char_t* defaultPath;
} nfdopendialogu8args_t;

#ifdef _WIN32
typedef struct {
const nfdnfilteritem_t* filterList;
nfdfiltersize_t filterCount;
const nfdnchar_t* defaultPath;
} nfdopendialognargs_t;
#else
typedef nfdopendialogu8args_t nfdopendialognargs_t;
#endif // _WIN32

// This is a unique identifier tagged to all the NFD_*With() function calls, for backward
// compatibility purposes. Users are not expected to directly use this.
#define NFD_INTERFACE_VERSION 1

/** Free a file path that was returned by the dialogs.
*
* Note: use NFD_PathSet_FreePathN() to free path from pathset instead of this function. */
Expand Down Expand Up @@ -134,6 +156,32 @@ NFD_API nfdresult_t NFD_OpenDialogU8(nfdu8char_t** outPath,
nfdfiltersize_t filterCount,
const nfdu8char_t* defaultPath);

/** This function is a library implementation detail. Please use NFD_OpenDialogN_With() instead. */
NFD_API nfdresult_t NFD_OpenDialogN_With_Impl(nfdversion_t version,
nfdnchar_t** outPath,
const nfdopendialognargs_t* args);

/** Single file open dialog, with additional parameters.
*
* It's the caller's responsibility to free `args.outPath` via NFD_FreePathN() if this function
* returns NFD_OKAY. See documentation of nfdopendialogargs_t for details. */
inline nfdresult_t NFD_OpenDialogN_With(nfdnchar_t** outPath, nfdopendialognargs_t args) {
return NFD_OpenDialogN_With_Impl(NFD_INTERFACE_VERSION, outPath, &args);
}

/** This function is a library implementation detail. Please use NFD_OpenDialogU8_With() instead. */
NFD_API nfdresult_t NFD_OpenDialogU8_With_Impl(nfdversion_t version,
nfdu8char_t** outPath,
const nfdopendialogu8args_t* args);

/** Single file open dialog, with additional parameters.
*
* It's the caller's responsibility to free `args.outPath` via NFD_FreePathU8() if this function
* returns NFD_OKAY. See documentation of nfdopendialogargs_t for details. */
inline nfdresult_t NFD_OpenDialogU8_With(nfdu8char_t** outPath, nfdopendialogu8args_t args) {
return NFD_OpenDialogU8_With_Impl(NFD_INTERFACE_VERSION, outPath, &args);
}

/** Multiple file open dialog
*
* It is the caller's responsibility to free `outPaths` via NFD_PathSet_FreeN() if this function
Expand All @@ -158,6 +206,32 @@ NFD_API nfdresult_t NFD_OpenDialogMultipleU8(const nfdpathset_t** outPaths,
nfdfiltersize_t filterCount,
const nfdu8char_t* defaultPath);

/** This function is a library implementation detail. Please use NFD_OpenDialogMultipleN_With() instead. */
NFD_API nfdresult_t NFD_OpenDialogMultipleN_With_Impl(nfdversion_t version,
const nfdpathset_t** outPaths,
const nfdopendialognargs_t* args);

/** Single file open dialog, with additional parameters.
*
* It's the caller's responsibility to free `args.outPath` via NFD_FreePathN() if this function
* returns NFD_OKAY. See documentation of nfdopendialogargs_t for details. */
inline nfdresult_t NFD_OpenDialogMultipleN_With(const nfdpathset_t** outPaths, nfdopendialognargs_t args) {
return NFD_OpenDialogMultipleN_With_Impl(NFD_INTERFACE_VERSION, outPaths, &args);
}

/** This function is a library implementation detail. Please use NFD_OpenDialogU8_With() instead. */
NFD_API nfdresult_t NFD_OpenDialogMultipleU8_With_Impl(nfdversion_t version,
const nfdpathset_t** outPaths,
const nfdopendialogu8args_t* args);

/** Single file open dialog, with additional parameters.
*
* It's the caller's responsibility to free `args.outPath` via NFD_FreePathU8() if this function
* returns NFD_OKAY. See documentation of nfdopendialogargs_t for details. */
inline nfdresult_t NFD_OpenDialogMultipleU8_With(const nfdpathset_t** outPaths, nfdopendialogu8args_t args) {
return NFD_OpenDialogMultipleU8_With_Impl(NFD_INTERFACE_VERSION, outPaths, &args);
}

/** Save dialog
*
* It is the caller's responsibility to free `outPath` via NFD_FreePathN() if this function returns
Expand Down
40 changes: 36 additions & 4 deletions src/nfd_cocoa.m
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,16 @@ nfdresult_t NFD_OpenDialogN(nfdnchar_t** outPath,
const nfdnfilteritem_t* filterList,
nfdfiltersize_t filterCount,
const nfdnchar_t* defaultPath) {
const nfdopendialognargs_t args = {filterList, filterCount, defaultPath};
return NFD_OpenDialogN_With_Impl(NFD_INTERFACE_VERSION, outPath, &args);
}

nfdresult_t NFD_OpenDialogN_With_Impl(nfdversion_t version,
nfdnchar_t** outPath,
const nfdopendialognargs_t* args) {
// We haven't needed to bump the interface version yet.
(void)version;

nfdresult_t result = NFD_CANCEL;
@autoreleasepool {
NSWindow* keyWindow = [[NSApplication sharedApplication] keyWindow];
Expand All @@ -223,10 +233,10 @@ nfdresult_t NFD_OpenDialogN(nfdnchar_t** outPath,
[dialog setAllowsMultipleSelection:NO];

// Build the filter list
AddFilterListToDialog(dialog, filterList, filterCount);
AddFilterListToDialog(dialog, args->filterList, args->filterCount);

// Set the starting directory
SetDefaultPath(dialog, defaultPath);
SetDefaultPath(dialog, args->defaultPath);

if ([dialog runModal] == NSModalResponseOK) {
const NSURL* url = [dialog URL];
Expand All @@ -247,10 +257,26 @@ nfdresult_t NFD_OpenDialogU8(nfdu8char_t** outPath,
return NFD_OpenDialogN(outPath, filterList, filterCount, defaultPath);
}

nfdresult_t NFD_OpenDialogU8_With_Impl(nfdversion_t version,
nfdu8char_t** outPath,
const nfdopendialogu8args_t* args) {
return NFD_OpenDialogN_With_Impl(version, outPath, args);
}

nfdresult_t NFD_OpenDialogMultipleN(const nfdpathset_t** outPaths,
const nfdnfilteritem_t* filterList,
nfdfiltersize_t filterCount,
const nfdnchar_t* defaultPath) {
const nfdopendialognargs_t args = {filterList, filterCount, defaultPath};
return NFD_OpenDialogMultipleN_With_Impl(NFD_INTERFACE_VERSION, outPaths, &args);
}

nfdresult_t NFD_OpenDialogMultipleN_With_Impl(nfdversion_t version,
const nfdpathset_t** outPaths,
const nfdopendialognargs_t* args){
// We haven't needed to bump the interface version yet.
(void)version;

nfdresult_t result = NFD_CANCEL;
@autoreleasepool {
NSWindow* keyWindow = [[NSApplication sharedApplication] keyWindow];
Expand All @@ -259,10 +285,10 @@ nfdresult_t NFD_OpenDialogMultipleN(const nfdpathset_t** outPaths,
[dialog setAllowsMultipleSelection:YES];

// Build the filter list
AddFilterListToDialog(dialog, filterList, filterCount);
AddFilterListToDialog(dialog, args->filterList, args->filterCount);

// Set the starting directory
SetDefaultPath(dialog, defaultPath);
SetDefaultPath(dialog, args->defaultPath);

if ([dialog runModal] == NSModalResponseOK) {
const NSArray* urls = [dialog URLs];
Expand All @@ -288,6 +314,12 @@ nfdresult_t NFD_OpenDialogMultipleU8(const nfdpathset_t** outPaths,
return NFD_OpenDialogMultipleN(outPaths, filterList, filterCount, defaultPath);
}

nfdresult_t NFD_OpenDialogMultipleU8_With_Impl(nfdversion_t version,
const nfdpathset_t** outPaths,
const nfdopendialogu8args_t* args) {
return NFD_OpenDialogMultipleN_With_Impl(version, outPaths, args);
}

nfdresult_t NFD_SaveDialogN(nfdnchar_t** outPath,
const nfdnfilteritem_t* filterList,
nfdfiltersize_t filterCount,
Expand Down
34 changes: 32 additions & 2 deletions src/nfd_gtk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,16 @@ nfdresult_t NFD_OpenDialogN(nfdnchar_t** outPath,
const nfdnfilteritem_t* filterList,
nfdfiltersize_t filterCount,
const nfdnchar_t* defaultPath) {
const nfdopendialognargs_t args{filterList, filterCount, defaultPath};
return NFD_OpenDialogN_With_Impl(NFD_INTERFACE_VERSION, outPath, &args);
}

nfdresult_t NFD_OpenDialogN_With_Impl(nfdversion_t version,
nfdnchar_t** outPath,
const nfdopendialognargs_t* args) {
// We haven't needed to bump the interface version yet.
(void)version;

GtkWidget* widget = gtk_file_chooser_dialog_new("Open File",
nullptr,
GTK_FILE_CHOOSER_ACTION_OPEN,
Expand All @@ -429,10 +439,10 @@ nfdresult_t NFD_OpenDialogN(nfdnchar_t** outPath,
Widget_Guard widgetGuard(widget);

/* Build the filter list */
AddFiltersToDialog(GTK_FILE_CHOOSER(widget), filterList, filterCount);
AddFiltersToDialog(GTK_FILE_CHOOSER(widget), args->filterList, args->filterCount);

/* Set the default path */
SetDefaultPath(GTK_FILE_CHOOSER(widget), defaultPath);
SetDefaultPath(GTK_FILE_CHOOSER(widget), args->defaultPath);

if (RunDialogWithFocus(GTK_DIALOG(widget)) == GTK_RESPONSE_ACCEPT) {
// write out the file name
Expand All @@ -450,10 +460,25 @@ nfdresult_t NFD_OpenDialogU8(nfdu8char_t** outPath,
const nfdu8char_t* defaultPath)
__attribute__((alias("NFD_OpenDialogN")));

nfdresult_t NFD_OpenDialogU8_With_Impl(nfdversion_t version,
nfdu8char_t** outPath,
const nfdopendialogu8args_t* args)
__attribute__((alias("NFD_OpenDialogN_With_Impl")));

nfdresult_t NFD_OpenDialogMultipleN(const nfdpathset_t** outPaths,
const nfdnfilteritem_t* filterList,
nfdfiltersize_t filterCount,
const nfdnchar_t* defaultPath) {
const nfdopendialognargs_t args{filterList, filterCount, defaultPath};
return NFD_OpenDialogMultipleN_With_Impl(NFD_INTERFACE_VERSION, outPaths, &args);
}

nfdresult_t NFD_OpenDialogMultipleN_With_Impl(nfdversion_t version,
const nfdpathset_t** outPaths,
const nfdopendialognargs_t* args) {
// We haven't needed to bump the interface version yet.
(void)version;

GtkWidget* widget = gtk_file_chooser_dialog_new("Open Files",
nullptr,
GTK_FILE_CHOOSER_ACTION_OPEN,
Expand Down Expand Up @@ -492,6 +517,11 @@ nfdresult_t NFD_OpenDialogMultipleU8(const nfdpathset_t** outPaths,
const nfdu8char_t* defaultPath)
__attribute__((alias("NFD_OpenDialogMultipleN")));

nfdresult_t NFD_OpenDialogMultipleU8_With_Impl(nfdversion_t version,
const nfdpathset_t** outPaths,
const nfdopendialogu8args_t* args)
__attribute__((alias("NFD_OpenDialogMultipleN_With_Impl")));

nfdresult_t NFD_SaveDialogN(nfdnchar_t** outPath,
const nfdnfilteritem_t* filterList,
nfdfiltersize_t filterCount,
Expand Down
34 changes: 32 additions & 2 deletions src/nfd_portal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1377,10 +1377,20 @@ nfdresult_t NFD_OpenDialogN(nfdnchar_t** outPath,
const nfdnfilteritem_t* filterList,
nfdfiltersize_t filterCount,
const nfdnchar_t* defaultPath) {
const nfdopendialognargs_t args{filterList, filterCount, defaultPath};
return NFD_OpenDialogN_With_Impl(NFD_INTERFACE_VERSION, outPath, &args);
}

nfdresult_t NFD_OpenDialogN_With_Impl(nfdversion_t version,
nfdnchar_t** outPath,
const nfdopendialognargs_t* args) {
// We haven't needed to bump the interface version yet.
(void)version;

DBusMessage* msg;
{
const nfdresult_t res =
NFD_DBus_OpenFile<false, false>(msg, filterList, filterCount, defaultPath);
const nfdresult_t res = NFD_DBus_OpenFile<false, false>(
msg, args->filterList, args->filterCount, args->defaultPath);
if (res != NFD_OKAY) {
return res;
}
Expand All @@ -1404,10 +1414,25 @@ nfdresult_t NFD_OpenDialogU8(nfdu8char_t** outPath,
const nfdu8char_t* defaultPath)
__attribute__((alias("NFD_OpenDialogN")));

nfdresult_t NFD_OpenDialogU8_With_Impl(nfdversion_t version,
nfdu8char_t** outPath,
const nfdopendialogu8args_t* args)
__attribute__((alias("NFD_OpenDialogN_With_Impl")));

nfdresult_t NFD_OpenDialogMultipleN(const nfdpathset_t** outPaths,
const nfdnfilteritem_t* filterList,
nfdfiltersize_t filterCount,
const nfdnchar_t* defaultPath) {
const nfdopendialognargs_t args{filterList, filterCount, defaultPath};
return NFD_OpenDialogMultipleN_With_Impl(NFD_INTERFACE_VERSION, outPaths, &args);
}

nfdresult_t NFD_OpenDialogMultipleN_With_Impl(nfdversion_t version,
const nfdpathset_t** outPaths,
const nfdopendialognargs_t* args) {
// We haven't needed to bump the interface version yet.
(void)version;

DBusMessage* msg;
{
const nfdresult_t res =
Expand All @@ -1434,6 +1459,11 @@ nfdresult_t NFD_OpenDialogMultipleU8(const nfdpathset_t** outPaths,
const nfdu8char_t* defaultPath)
__attribute__((alias("NFD_OpenDialogMultipleN")));

nfdresult_t NFD_OpenDialogMultipleU8_With_Impl(nfdversion_t version,
const nfdpathset_t** outPaths,
const nfdopendialogu8args_t* args)
__attribute__((alias("NFD_OpenDialogMultipleN_With_Impl")));

nfdresult_t NFD_SaveDialogN(nfdnchar_t** outPath,
const nfdnfilteritem_t* filterList,
nfdfiltersize_t filterCount,
Expand Down
Loading

0 comments on commit 552d463

Please sign in to comment.