--- hatari/src/gui-sdl/dlgFileSelect.c 2019/04/09 08:47:27 1.1.1.7 +++ hatari/src/gui-sdl/dlgFileSelect.c 2019/04/09 08:54:40 1.1.1.12 @@ -1,8 +1,8 @@ /* Hatari - dlgFileSelect.c - This file is distributed under the GNU Public License, version 2 or at - your option any later version. Read the file gpl.txt for details. + This file is distributed under the GNU General Public License, version 2 + or at your option any later version. Read the file gpl.txt for details. A file selection dialog for the graphical user interface for Hatari. */ @@ -16,24 +16,29 @@ const char DlgFileSelect_fileid[] = "Hat #include "scandir.h" #include "sdlgui.h" #include "file.h" +#include "paths.h" #include "zip.h" #define SGFS_NUMENTRIES 16 /* How many entries are displayed at once */ -#define SGFSDLG_FILENAME 5 -#define SGFSDLG_UPDIR 6 -#define SGFSDLG_HOMEDIR 7 -#define SGFSDLG_ROOTDIR 8 -#define SGFSDLG_ENTRY1 11 -#define SGFSDLG_ENTRY16 26 -#define SGFSDLG_UP 27 -#define SGFSDLG_DOWN 28 -#define SGFSDLG_SHOWHIDDEN 29 -#define SGFSDLG_OKAY 30 -#define SGFSDLG_CANCEL 31 +#define SGFSDLG_FILENAME 5 +#define SGFSDLG_UPDIR 6 +#define SGFSDLG_CWD 7 +#define SGFSDLG_HOMEDIR 8 +#define SGFSDLG_ROOTDIR 9 +#define SGFSDLG_ENTRYFIRST 12 +#define SGFSDLG_ENTRYLAST 27 +#define SGFSDLG_SCROLLBAR 28 +#define SGFSDLG_UP 29 +#define SGFSDLG_DOWN 30 +#define SGFSDLG_SHOWHIDDEN 31 +#define SGFSDLG_OKAY 32 +#define SGFSDLG_CANCEL 33 +#define SCROLLOUT_ABOVE 1 +#define SCROLLOUT_UNDER 2 #define DLGPATH_SIZE 62 static char dlgpath[DLGPATH_SIZE+1]; /* Path name in the dialog */ @@ -44,6 +49,8 @@ static char dlgfname[DLGFNAME_SIZE+1]; #define DLGFILENAMES_SIZE 59 static char dlgfilenames[SGFS_NUMENTRIES][DLGFILENAMES_SIZE+1]; /* Visible file names in the dialog */ +#define SCROLLBAR_MIN_HEIGHT 4 /* Min value for yScrollbar_size */ + /* The dialog data: */ static SGOBJ fsdlg[] = { @@ -53,7 +60,8 @@ static SGOBJ fsdlg[] = { SGTEXT, 0, 0, 1,3, DLGPATH_SIZE,1, dlgpath }, { SGTEXT, 0, 0, 1,4, 6,1, "File:" }, { SGTEXT, 0, 0, 7,4, DLGFNAME_SIZE,1, dlgfname }, - { SGBUTTON, 0, 0, 51,1, 4,1, ".." }, + { SGBUTTON, 0, 0, 45,1, 4,1, ".." }, + { SGBUTTON, 0, 0, 50,1, 5,1, "CWD" }, { SGBUTTON, 0, 0, 56,1, 3,1, "~" }, { SGBUTTON, 0, 0, 60,1, 3,1, "/" }, { SGBOX, 0, 0, 1,6, 62,16, NULL }, @@ -74,8 +82,9 @@ static SGOBJ fsdlg[] = { SGTEXT, SG_EXIT, 0, 2,19, DLGFILENAMES_SIZE,1, dlgfilenames[13] }, { SGTEXT, SG_EXIT, 0, 2,20, DLGFILENAMES_SIZE,1, dlgfilenames[14] }, { SGTEXT, SG_EXIT, 0, 2,21, DLGFILENAMES_SIZE,1, dlgfilenames[15] }, - { SGBUTTON, SG_TOUCHEXIT, 0, 62,6, 1,1, "\x01" }, /* Arrow up */ - { SGBUTTON, SG_TOUCHEXIT, 0, 62,21, 1,1, "\x02" }, /* Arrow down */ + { SGSCROLLBAR, SG_TOUCHEXIT, 0, 62, 7, 0, 0, NULL }, /* Scrollbar */ + { SGBUTTON, SG_TOUCHEXIT, 0, 62, 6,1,1, "\x01" }, /* Arrow up */ + { SGBUTTON, SG_TOUCHEXIT, 0, 62,21,1,1, "\x02" }, /* Arrow down */ { SGCHECKBOX, SG_EXIT, 0, 2,23, 18,1, "Show hidden files" }, { SGBUTTON, SG_DEFAULT, 0, 32,23, 8,1, "Okay" }, { SGBUTTON, SG_CANCEL, 0, 50,23, 8,1, "Cancel" }, @@ -83,16 +92,25 @@ static SGOBJ fsdlg[] = }; -static int ypos; /* First entry number to be displayed */ -static bool refreshentries; /* Do we have to update the file names in the dialog? */ -static int entries; /* How many files are in the actual directory? */ +static int ypos = -1; /* First entry number to be displayed. If -1, file selector start on the 1st file */ + /* else we continue from the previous position when SDLGui_FileSelect is called again */ +static bool refreshentries; /* Do we have to update the file names in the dialog? */ +static int entries; /* How many files are in the actual directory? */ +static int oldMouseY = 0; /* Keep the latest Y mouse position for scrollbar move computing */ +static int mouseClicked = 0; /* used to know if mouse if down for the first time or not */ +static int mouseIsOut = 0; /* used to keep info that mouse if above or under the scrollbar when mousebutton is down */ +static float scrollbar_Ypos = 0.0; /* scrollbar heigth */ + +/* Convert file position (in file list) to scrollbar y position */ +static void DlgFileSelect_Convert_ypos_to_scrollbar_Ypos(void); + /*-----------------------------------------------------------------------*/ -/* - Update the file name strings in the dialog. - Returns false if it failed, true on success. -*/ +/** + * Update the file name strings in the dialog. + * Returns false if it failed, true on success. + */ static int DlgFileSelect_RefreshEntries(struct dirent **files, char *path, bool browsingzip) { int i; @@ -141,10 +159,10 @@ static int DlgFileSelect_RefreshEntries( /*-----------------------------------------------------------------------*/ -/* - Remove all hidden files (files with file names that begin with a dot) from - the list. -*/ +/** + * Remove all hidden files (files with file names that begin with a dot) from + * the list. + */ static void DlgFileSelect_RemoveHiddenFiles(struct dirent **files) { int i; @@ -186,37 +204,119 @@ static void DlgFileSelect_RemoveHiddenFi /*-----------------------------------------------------------------------*/ -/* - Prepare to scroll up one entry. -*/ +/** + * Prepare to scroll up one entry. + */ static void DlgFileSelect_ScrollUp(void) { if (ypos > 0) { --ypos; + DlgFileSelect_Convert_ypos_to_scrollbar_Ypos(); refreshentries = true; } } /*-----------------------------------------------------------------------*/ -/* - Prepare to scroll down one entry. -*/ +/** + * Prepare to scroll down one entry. + */ static void DlgFileSelect_ScrollDown(void) { if (ypos+SGFS_NUMENTRIES < entries) { ++ypos; + DlgFileSelect_Convert_ypos_to_scrollbar_Ypos(); refreshentries = true; } } +/*-----------------------------------------------------------------------*/ +/** + * Manage the scrollbar up or down. + */ +static void DlgFileSelect_ManageScrollbar(void) +{ + int b, x, y; + int scrollY, scrollYmin, scrollYmax, scrollH_half; + float scrollMove; + + SDL_GetMouseState(&x, &y); + + /* If mouse is down on the scrollbar for the first time */ + if (fsdlg[SGFSDLG_SCROLLBAR].state & SG_MOUSEDOWN) { + if (mouseClicked == 0) { + mouseClicked = 1; + mouseIsOut = 0; + oldMouseY = y; + } + } + /* Mouse button is up on the scrollbar */ + else { + mouseClicked = 0; + oldMouseY = y; + mouseIsOut = 0; + } + + /* If mouse Y position didn't change */ + if (oldMouseY == y) + return; + + /* Compute scrollbar ymin and ymax values */ + + scrollYmin = (fsdlg[SGFSDLG_SCROLLBAR].y + fsdlg[0].y) * sdlgui_fontheight; + scrollYmax = (fsdlg[SGFSDLG_DOWN].y + fsdlg[0].y) * sdlgui_fontheight; + + scrollY = fsdlg[SGFSDLG_SCROLLBAR].y * sdlgui_fontheight + fsdlg[SGFSDLG_SCROLLBAR].h + fsdlg[0].y * sdlgui_fontheight; + scrollH_half = scrollY + fsdlg[SGFSDLG_SCROLLBAR].w / 2; + scrollMove = (float)(y-oldMouseY)/sdlgui_fontheight; + + /* Verify if mouse is not above the scrollbar area */ + if (y < scrollYmin) { + mouseIsOut = SCROLLOUT_ABOVE; + oldMouseY = y; + return; + } + if (mouseIsOut == SCROLLOUT_ABOVE && y < scrollH_half) { + oldMouseY = y; + return; + } + + /* Verify if mouse is not under the scrollbar area */ + if (y > scrollYmax) { + mouseIsOut = SCROLLOUT_UNDER; + oldMouseY = y; + return; + } + if (mouseIsOut == SCROLLOUT_UNDER && y > scrollH_half) { + oldMouseY = y; + return; + } + + mouseIsOut = 0; + + scrollbar_Ypos += scrollMove; + oldMouseY = y; + + /* Verifiy if scrollbar is in correct inferior boundary */ + if (scrollbar_Ypos < 0) + scrollbar_Ypos = 0.0; + + /* Verifiy if scrollbar is in correct superior boundary */ + b = (int) (scrollbar_Ypos * ((float)entries/(float)(SGFS_NUMENTRIES-2)) + 0.5); + if (b+SGFS_NUMENTRIES >= entries) { + ypos = entries - SGFS_NUMENTRIES; + DlgFileSelect_Convert_ypos_to_scrollbar_Ypos(); + } + + refreshentries = true; +} /*-----------------------------------------------------------------------*/ -/* - Handle SDL events. -*/ +/** + * Handle SDL events. + */ static void DlgFileSelect_HandleSdlEvents(SDL_Event *pEvent) { int oldypos = ypos; @@ -228,19 +328,33 @@ static void DlgFileSelect_HandleSdlEvent else if (pEvent->button.button == SDL_BUTTON_WHEELDOWN) DlgFileSelect_ScrollDown(); break; - case SDL_KEYDOWN: + case SDL_KEYDOWN: switch (pEvent->key.keysym.sym) { - case SDLK_UP: DlgFileSelect_ScrollUp(); break; - case SDLK_DOWN: DlgFileSelect_ScrollDown(); break; - case SDLK_HOME: ypos = 0; break; - case SDLK_END: ypos = entries-SGFS_NUMENTRIES; break; - case SDLK_PAGEUP: ypos -= SGFS_NUMENTRIES; break; + case SDLK_UP: + DlgFileSelect_ScrollUp(); + break; + case SDLK_DOWN: + DlgFileSelect_ScrollDown(); + break; + case SDLK_HOME: + ypos = 0; + DlgFileSelect_Convert_ypos_to_scrollbar_Ypos(); + break; + case SDLK_END: + ypos = entries-SGFS_NUMENTRIES; + DlgFileSelect_Convert_ypos_to_scrollbar_Ypos(); + break; + case SDLK_PAGEUP: + ypos -= SGFS_NUMENTRIES; + DlgFileSelect_Convert_ypos_to_scrollbar_Ypos(); + break; case SDLK_PAGEDOWN: if (ypos+2*SGFS_NUMENTRIES < entries) ypos += SGFS_NUMENTRIES; else ypos = entries-SGFS_NUMENTRIES; + DlgFileSelect_Convert_ypos_to_scrollbar_Ypos(); break; default: break; @@ -249,17 +363,21 @@ static void DlgFileSelect_HandleSdlEvent default: break; } - if (ypos < 0) + + if (ypos < 0) { ypos = 0; + scrollbar_Ypos = 0.0; + } + if (ypos != oldypos) refreshentries = true; } /*-----------------------------------------------------------------------*/ -/* - Free file entries -*/ +/** + * Free file entries + */ static struct dirent **files_free(struct dirent **files) { int i; @@ -276,10 +394,10 @@ static struct dirent **files_free(struct /*-----------------------------------------------------------------------*/ -/* - Copy to dst src+add if they are below maxlen and return true, - otherwise return false -*/ +/** + * Copy to dst src+add if they are below maxlen and return true, + * otherwise return false + */ static int strcat_maxlen(char *dst, int maxlen, const char *src, const char *add) { int slen, alen; @@ -295,9 +413,9 @@ static int strcat_maxlen(char *dst, int } /*-----------------------------------------------------------------------*/ -/* - Create and return suitable path into zip file -*/ +/** + * Create and return suitable path into zip file + */ static char* zip_get_path(const char *zipdir, const char *zipfilename, int browsingzip) { if (browsingzip) @@ -311,7 +429,9 @@ static char* zip_get_path(const char *zi return strdup(""); } -/* string for zip root needs to be empty, check and correct if needed */ +/** + * string for zip root needs to be empty, check and correct if needed + */ static void correct_zip_root(char *zippath) { if (zippath[0] == PATHSEP && !zippath[1]) @@ -320,31 +440,52 @@ static void correct_zip_root(char *zippa } } +/** + * Convert Ypos to Y scrollbar position + */ +static void DlgFileSelect_Convert_ypos_to_scrollbar_Ypos(void) +{ + if (entries <= SGFS_NUMENTRIES) + scrollbar_Ypos = 0.0; + else + scrollbar_Ypos = (float)ypos / ((float)entries/(float)(SGFS_NUMENTRIES-2)); +} + /*-----------------------------------------------------------------------*/ -/* - Show and process a file selection dialog. - Returns path/name user selected or NULL if user canceled - input: zip_path = pointer's pointer to buffer to contain file path - within a selected zip file, or NULL if browsing zip files is disallowed. - bAllowNew: true if the user is allowed to insert new file names. -*/ +/** + * Show and process a file selection dialog. + * Returns path/name user selected or NULL if user canceled + * input: zip_path = pointer's pointer to buffer to contain file path + * within a selected zip file, or NULL if browsing zip files is disallowed. + * bAllowNew: true if the user is allowed to insert new file names. + */ char* SDLGui_FileSelect(const char *path_and_name, char **zip_path, bool bAllowNew) { struct dirent **files = NULL; char *pStringMem; - char *retpath; - char *home, *path, *fname; /* The actual file and path names */ + char *retpath = NULL; + const char *home; + char *path, *fname; /* The actual file and path names */ bool reloaddir = true; /* Do we have to reload the directory file list? */ int retbut; - int oldcursorstate; - int selection = -1; /* The actual selection, -1 if none selected */ + bool bOldMouseVisibility; + int selection; /* The selection index */ char *zipfilename; /* Filename in zip file */ char *zipdir; bool browsingzip = false; /* Are we browsing an archive? */ zip_dir *zipfiles = NULL; SDL_Event sdlEvent; + int yScrollbar_size; /* Size of the vertical scrollbar */ + + /* If this is the first call to SDLGui_FileSelect, we reset scrollbar_Ypos and ypos */ + /* Else, we keep the previous value of scrollbar_Ypos and update ypos below, to open */ + /* the fileselector at the same position it was used */ + if ( ypos < 0 ) + { + scrollbar_Ypos = 0.0; + ypos = 0; + } - ypos = 0; refreshentries = true; entries = 0; @@ -358,6 +499,10 @@ char* SDLGui_FileSelect(const char *path fname[0] = 0; path[0] = 0; + /* Save mouse state and enable cursor */ + bOldMouseVisibility = SDL_ShowCursor(SDL_QUERY); + SDL_ShowCursor(SDL_ENABLE); + SDLGui_CenterDlg(fsdlg); if (bAllowNew) { @@ -382,7 +527,7 @@ char* SDLGui_FileSelect(const char *path if (!(File_DirExists(path) || getcwd(path, FILENAME_MAX))) { perror("SDLGui_FileSelect: non-existing path and CWD failed"); - return NULL; + goto clean_exit; } } @@ -391,11 +536,6 @@ char* SDLGui_FileSelect(const char *path File_ShrinkName(dlgpath, path, DLGPATH_SIZE); File_ShrinkName(dlgfname, fname, DLGFNAME_SIZE); - /* Save old mouse cursor state and enable cursor */ - oldcursorstate = SDL_ShowCursor(SDL_QUERY); - if (oldcursorstate == SDL_DISABLE) - SDL_ShowCursor(SDL_ENABLE); - do { if (reloaddir) @@ -405,6 +545,11 @@ char* SDLGui_FileSelect(const char *path if (browsingzip) { files = ZIP_GetFilesDir(zipfiles, zipdir, &entries); + if(!files) + { + fprintf(stderr, "SDLGui_FileSelect: ZIP_GetFilesDir error!\n"); + goto clean_exit; + } } else { @@ -421,8 +566,7 @@ char* SDLGui_FileSelect(const char *path if (entries < 0) { fprintf(stderr, "SDLGui_FileSelect: Path not found.\n"); - free(pStringMem); - return NULL; + goto clean_exit; } /* reload always implies refresh */ @@ -430,13 +574,34 @@ char* SDLGui_FileSelect(const char *path refreshentries = true; }/* reloaddir */ + /* Refresh scrollbar size */ + if (entries <= SGFS_NUMENTRIES) + yScrollbar_size = (SGFS_NUMENTRIES-2) * sdlgui_fontheight; + else + { + yScrollbar_size = (int)((SGFS_NUMENTRIES-2) / ((float)entries/(float)SGFS_NUMENTRIES) * sdlgui_fontheight); + if ( yScrollbar_size < SCROLLBAR_MIN_HEIGHT ) /* Value could be 0 for very large directory */ + yScrollbar_size = SCROLLBAR_MIN_HEIGHT; + } + fsdlg[SGFSDLG_SCROLLBAR].w = yScrollbar_size; + + /* Refresh scrolbar pos */ + ypos = (int) (scrollbar_Ypos * ((float)entries/(float)(SGFS_NUMENTRIES-2)) + 0.5); + + if (ypos+SGFS_NUMENTRIES >= entries) { /* Ensure Y pos is in the correct boundaries */ + ypos = entries - SGFS_NUMENTRIES; + if ( ypos < 0 ) + ypos = 0; + DlgFileSelect_Convert_ypos_to_scrollbar_Ypos(); + } + fsdlg[SGFSDLG_SCROLLBAR].h = (int) (scrollbar_Ypos * sdlgui_fontheight); + /* Update the file name strings in the dialog? */ if (refreshentries) { if (!DlgFileSelect_RefreshEntries(files, path, browsingzip)) { - free(pStringMem); - return NULL; + goto clean_exit; } refreshentries = false; } @@ -445,7 +610,7 @@ char* SDLGui_FileSelect(const char *path retbut = SDLGui_DoDialog(fsdlg, &sdlEvent); /* Has the user clicked on a file or folder? */ - if (retbut>=SGFSDLG_ENTRY1 && retbut<=SGFSDLG_ENTRY16 && retbut-SGFSDLG_ENTRY1+ypos=SGFSDLG_ENTRYFIRST && retbut<=SGFSDLG_ENTRYLAST && retbut-SGFSDLG_ENTRYFIRST+yposd_name)) + zipdir, files[retbut-SGFSDLG_ENTRYFIRST+ypos]->d_name)) { fprintf(stderr, "SDLGui_FileSelect: Path name too long!\n"); - free(pStringMem); - return NULL; + free(tempstr); + goto clean_exit; } /* directory? */ if (File_DoesFileNameEndWithSlash(tempstr)) { /* handle the ../ directory */ - if (strcmp(files[retbut-SGFSDLG_ENTRY1+ypos]->d_name, "../") == 0) + if (strcmp(files[retbut-SGFSDLG_ENTRYFIRST+ypos]->d_name, "../") == 0) { /* close the zip file */ if (strcmp(tempstr, "../") == 0) @@ -498,15 +662,15 @@ char* SDLGui_FileSelect(const char *path } reloaddir = true; /* Copy the path name to the dialog */ - selection = -1; /* Remove old selection */ zipfilename[0] = '\0'; dlgfname[0] = 0; ypos = 0; + scrollbar_Ypos = 0.0; } else { /* not dir, select a file in the zip */ - selection = retbut-SGFSDLG_ENTRY1+ypos; + selection = retbut-SGFSDLG_ENTRYFIRST+ypos; strcpy(zipfilename, files[selection]->d_name); File_ShrinkName(dlgfname, zipfilename, DLGFNAME_SIZE); } @@ -515,11 +679,11 @@ char* SDLGui_FileSelect(const char *path else /* not browsingzip */ { if (!strcat_maxlen(tempstr, FILENAME_MAX, - path, files[retbut-SGFSDLG_ENTRY1+ypos]->d_name)) + path, files[retbut-SGFSDLG_ENTRYFIRST+ypos]->d_name)) { fprintf(stderr, "SDLGui_FileSelect: Path name too long!\n"); - free(pStringMem); - return NULL; + free(tempstr); + goto clean_exit; } if (File_DirExists(tempstr)) { @@ -529,9 +693,9 @@ char* SDLGui_FileSelect(const char *path File_ShrinkName(dlgpath, tempstr, DLGPATH_SIZE); strcpy(path, tempstr); reloaddir = true; - selection = -1; /* Remove old selection */ dlgfname[0] = 0; ypos = 0; + scrollbar_Ypos = 0.0; } else if (ZIP_FileNameIsZIP(tempstr) && zip_path != NULL) { @@ -539,7 +703,7 @@ char* SDLGui_FileSelect(const char *path zipfiles = ZIP_GetFiles(tempstr); if (zipfiles != NULL && browsingzip == false) { - selection = retbut-SGFSDLG_ENTRY1+ypos; + selection = retbut-SGFSDLG_ENTRYFIRST+ypos; strcpy(fname, files[selection]->d_name); File_ShrinkName(dlgfname, fname, DLGFNAME_SIZE); browsingzip = true; @@ -547,13 +711,14 @@ char* SDLGui_FileSelect(const char *path File_ShrinkName(dlgpath, zipdir, DLGPATH_SIZE); reloaddir = true; ypos = 0; + scrollbar_Ypos = 0.0; } } else { /* Select a file */ - selection = retbut-SGFSDLG_ENTRY1+ypos; + selection = retbut-SGFSDLG_ENTRYFIRST+ypos; strcpy(fname, files[selection]->d_name); File_ShrinkName(dlgfname, fname, DLGFNAME_SIZE); } @@ -567,7 +732,6 @@ char* SDLGui_FileSelect(const char *path switch(retbut) { case SGFSDLG_UPDIR: /* Change path to parent directory */ - if (browsingzip) { /* close the zip file? */ @@ -597,8 +761,12 @@ char* SDLGui_FileSelect(const char *path break; case SGFSDLG_HOMEDIR: /* Change to home directory */ - home = getenv("HOME"); - if (home == NULL) + case SGFSDLG_CWD: /* Change to current work directory */ + if (retbut == SGFSDLG_CWD) + home = Paths_GetWorkingDir(); + else + home = Paths_GetUserHome(); + if (home == NULL || !*home) break; if (browsingzip) { @@ -633,12 +801,17 @@ char* SDLGui_FileSelect(const char *path DlgFileSelect_ScrollDown(); SDL_Delay(10); break; + case SGFSDLG_SCROLLBAR: /* Scrollbar selected */ + DlgFileSelect_ManageScrollbar(); + SDL_Delay(10); + break; case SGFSDLG_FILENAME: /* User entered new filename */ strcpy(fname, dlgfname); break; case SGFSDLG_SHOWHIDDEN: /* Show/hide hidden files */ reloaddir = true; ypos = 0; + scrollbar_Ypos = 0.0; break; case SDLGUI_UNKNOWNEVENT: DlgFileSelect_HandleSdlEvents(&sdlEvent); @@ -648,10 +821,10 @@ char* SDLGui_FileSelect(const char *path if (reloaddir) { /* Remove old selection */ - selection = -1; fname[0] = 0; dlgfname[0] = 0; ypos = 0; + scrollbar_Ypos = 0.0; } } /* other button code */ @@ -660,9 +833,6 @@ char* SDLGui_FileSelect(const char *path while (retbut!=SGFSDLG_OKAY && retbut!=SGFSDLG_CANCEL && retbut!=SDLGUI_QUIT && retbut != SDLGUI_ERROR && !bQuitProgram); - if (oldcursorstate == SDL_DISABLE) - SDL_ShowCursor(SDL_DISABLE); - files_free(files); if (browsingzip) @@ -680,19 +850,22 @@ char* SDLGui_FileSelect(const char *path } else retpath = NULL; +clean_exit: + SDL_ShowCursor(bOldMouseVisibility); free(pStringMem); return retpath; } /*-----------------------------------------------------------------------*/ -/* Let user browse for a file, confname is used as default. +/** + * Let user browse for a file, confname is used as default. * If bAllowNew is true, user can select new files also. * * If no file is selected, or there's some problem with the file, * return false and clear dlgname & confname. * Otherwise return true, set dlgname & confname to the new file name - * (dlgname is shrinked & limited to maxlen and confname is assumed + * (dlgname is shrunken & limited to maxlen and confname is assumed * to have FILENAME_MAX amount of space). */ bool SDLGui_FileConfSelect(char *dlgname, char *confname, int maxlen, bool bAllowNew)