Annotation of hatari/src/gui-sdl/dlgFileSelect.c, revision 1.1.1.13

1.1       root        1: /*
                      2:   Hatari - dlgFileSelect.c
1.1.1.13! root        3: 
1.1.1.11  root        4:   This file is distributed under the GNU General Public License, version 2
                      5:   or at your option any later version. Read the file gpl.txt for details.
1.1.1.13! root        6: 
1.1       root        7:   A file selection dialog for the graphical user interface for Hatari.
                      8: */
1.1.1.7   root        9: const char DlgFileSelect_fileid[] = "Hatari dlgFileSelect.c : " __DATE__ " " __TIME__;
1.1       root       10: 
                     11: #include <SDL.h>
                     12: #include <sys/stat.h>
                     13: #include <unistd.h>
                     14: 
                     15: #include "main.h"
1.1.1.3   root       16: #include "scandir.h"
1.1       root       17: #include "sdlgui.h"
                     18: #include "file.h"
1.1.1.8   root       19: #include "paths.h"
1.1       root       20: #include "zip.h"
                     21: 
                     22: 
1.1.1.2   root       23: #define SGFS_NUMENTRIES   16            /* How many entries are displayed at once */
                     24: 
1.1.1.13! root       25: #define SGFSDLG_TITLE       1
1.1.1.11  root       26: #define SGFSDLG_FILENAME    5
                     27: #define SGFSDLG_UPDIR       6
                     28: #define SGFSDLG_CWD         7
                     29: #define SGFSDLG_HOMEDIR     8
                     30: #define SGFSDLG_ROOTDIR     9
                     31: #define SGFSDLG_ENTRYFIRST 12
                     32: #define SGFSDLG_ENTRYLAST  27
                     33: #define SGFSDLG_SCROLLBAR  28
                     34: #define SGFSDLG_UP         29
                     35: #define SGFSDLG_DOWN       30
                     36: #define SGFSDLG_SHOWHIDDEN 31
                     37: #define SGFSDLG_OKAY       32
                     38: #define SGFSDLG_CANCEL     33
1.1       root       39: 
1.1.1.9   root       40: #define SCROLLOUT_ABOVE  1
                     41: #define SCROLLOUT_UNDER  2
1.1       root       42: 
                     43: #define DLGPATH_SIZE 62
                     44: static char dlgpath[DLGPATH_SIZE+1];    /* Path name in the dialog */
                     45: 
                     46: #define DLGFNAME_SIZE 56
                     47: static char dlgfname[DLGFNAME_SIZE+1];  /* Name of the selected file in the dialog */
                     48: 
                     49: #define DLGFILENAMES_SIZE 59
1.1.1.2   root       50: static char dlgfilenames[SGFS_NUMENTRIES][DLGFILENAMES_SIZE+1];  /* Visible file names in the dialog */
1.1       root       51: 
1.1.1.11  root       52: #define SCROLLBAR_MIN_HEIGHT 4         /* Min value for yScrollbar_size */
                     53: 
1.1.1.13! root       54: #define TITLE_OFFSET 1
        !            55: #define TITLE_MAXLEN 40
        !            56: 
1.1       root       57: /* The dialog data: */
                     58: static SGOBJ fsdlg[] =
                     59: {
                     60:        { SGBOX, 0, 0, 0,0, 64,25, NULL },
1.1.1.13! root       61:        { SGTEXT, 0, 0, 1,1, 13,1, NULL, },
1.1       root       62:        { SGTEXT, 0, 0, 1,2, 7,1, "Folder:" },
                     63:        { SGTEXT, 0, 0, 1,3, DLGPATH_SIZE,1, dlgpath },
                     64:        { SGTEXT, 0, 0, 1,4, 6,1, "File:" },
                     65:        { SGTEXT, 0, 0, 7,4, DLGFNAME_SIZE,1, dlgfname },
1.1.1.13! root       66:        { SGBUTTON, 0, 0, 39,1, 4,1, "_Up" },
        !            67:        { SGBUTTON, 0, 0, 44,1, 5,1, "_CWD" },
        !            68:        { SGBUTTON, 0, 0, 50,1, 6,1, "_Home" },
        !            69:        { SGBUTTON, 0, 0, 57,1, 6,1, "_Root" },
1.1       root       70:        { SGBOX, 0, 0, 1,6, 62,16, NULL },
                     71:        { SGBOX, 0, 0, 62,7, 1,14, NULL },
                     72:        { SGTEXT, SG_EXIT, 0, 2,6, DLGFILENAMES_SIZE,1, dlgfilenames[0] },
                     73:        { SGTEXT, SG_EXIT, 0, 2,7, DLGFILENAMES_SIZE,1, dlgfilenames[1] },
                     74:        { SGTEXT, SG_EXIT, 0, 2,8, DLGFILENAMES_SIZE,1, dlgfilenames[2] },
                     75:        { SGTEXT, SG_EXIT, 0, 2,9, DLGFILENAMES_SIZE,1, dlgfilenames[3] },
                     76:        { SGTEXT, SG_EXIT, 0, 2,10, DLGFILENAMES_SIZE,1, dlgfilenames[4] },
                     77:        { SGTEXT, SG_EXIT, 0, 2,11, DLGFILENAMES_SIZE,1, dlgfilenames[5] },
                     78:        { SGTEXT, SG_EXIT, 0, 2,12, DLGFILENAMES_SIZE,1, dlgfilenames[6] },
                     79:        { SGTEXT, SG_EXIT, 0, 2,13, DLGFILENAMES_SIZE,1, dlgfilenames[7] },
                     80:        { SGTEXT, SG_EXIT, 0, 2,14, DLGFILENAMES_SIZE,1, dlgfilenames[8] },
                     81:        { SGTEXT, SG_EXIT, 0, 2,15, DLGFILENAMES_SIZE,1, dlgfilenames[9] },
                     82:        { SGTEXT, SG_EXIT, 0, 2,16, DLGFILENAMES_SIZE,1, dlgfilenames[10] },
                     83:        { SGTEXT, SG_EXIT, 0, 2,17, DLGFILENAMES_SIZE,1, dlgfilenames[11] },
                     84:        { SGTEXT, SG_EXIT, 0, 2,18, DLGFILENAMES_SIZE,1, dlgfilenames[12] },
                     85:        { SGTEXT, SG_EXIT, 0, 2,19, DLGFILENAMES_SIZE,1, dlgfilenames[13] },
                     86:        { SGTEXT, SG_EXIT, 0, 2,20, DLGFILENAMES_SIZE,1, dlgfilenames[14] },
                     87:        { SGTEXT, SG_EXIT, 0, 2,21, DLGFILENAMES_SIZE,1, dlgfilenames[15] },
1.1.1.9   root       88:        { SGSCROLLBAR, SG_TOUCHEXIT, 0, 62, 7, 0, 0, NULL },       /* Scrollbar */
1.1.1.13! root       89:        { SGBUTTON,   SG_TOUCHEXIT, 0, 62, 6,1,1, "\x01", SG_SHORTCUT_UP },
        !            90:        { SGBUTTON,   SG_TOUCHEXIT, 0, 62,21,1,1, "\x02", SG_SHORTCUT_DOWN },
        !            91:        { SGCHECKBOX, SG_EXIT, 0, 2,23, 19,1, "_Show hidden files" },
        !            92:        { SGBUTTON, SG_DEFAULT, 0, 32,23, 8,1, "OK" },
1.1.1.4   root       93:        { SGBUTTON, SG_CANCEL, 0, 50,23, 8,1, "Cancel" },
1.1       root       94:        { -1, 0, 0, 0,0, 0,0, NULL }
                     95: };
                     96: 
                     97: 
1.1.1.11  root       98: static int ypos = -1;                          /* First entry number to be displayed. If -1, file selector start on the 1st file */
                     99:                                                /* else we continue from the previous position when SDLGui_FileSelect is called again */
                    100: static bool refreshentries;                    /* Do we have to update the file names in the dialog? */
                    101: static int entries;                            /* How many files are in the actual directory? */
                    102: static int oldMouseY = 0;                      /* Keep the latest Y mouse position for scrollbar move computing */
1.1.1.9   root      103: static int mouseClicked = 0;                   /* used to know if mouse if down for the first time or not */
1.1.1.11  root      104: static int mouseIsOut = 0;                     /* used to keep info that mouse if above or under the scrollbar when mousebutton is down */
                    105: static float scrollbar_Ypos = 0.0;             /* scrollbar heigth */
1.1.1.9   root      106: 
1.1.1.13! root      107: static char *dirpath;                          /* for get_dtype() */
        !           108: #ifndef HAVE_DIRENT_D_TYPE
        !           109: enum {
        !           110:        DT_UNKNOWN,
        !           111:        DT_LNK,
        !           112:        DT_DIR,
        !           113:        DT_REG
        !           114: };
        !           115: #endif
        !           116: 
1.1.1.9   root      117: /* Convert file position (in file list) to scrollbar y position */
                    118: static void DlgFileSelect_Convert_ypos_to_scrollbar_Ypos(void);
                    119: 
1.1.1.2   root      120: 
1.1       root      121: 
                    122: /*-----------------------------------------------------------------------*/
1.1.1.8   root      123: /**
                    124:  * Update the file name strings in the dialog.
                    125:  * Returns false if it failed, true on success.
                    126:  */
1.1.1.5   root      127: static int DlgFileSelect_RefreshEntries(struct dirent **files, char *path, bool browsingzip)
1.1       root      128: {
                    129:        int i;
                    130:        char *tempstr = malloc(FILENAME_MAX);
                    131: 
                    132:        if (!tempstr)
                    133:        {
                    134:                perror("DlgFileSelect_RefreshEntries");
1.1.1.7   root      135:                return false;
1.1       root      136:        }
                    137: 
                    138:        /* Copy entries to dialog: */
1.1.1.4   root      139:        for (i=0; i<SGFS_NUMENTRIES; i++)
1.1       root      140:        {
1.1.1.4   root      141:                if (i+ypos < entries)
1.1       root      142:                {
                    143:                        struct stat filestat;
                    144:                        /* Prepare entries: */
                    145:                        strcpy(tempstr, "  ");
                    146:                        strcat(tempstr, files[i+ypos]->d_name);
                    147:                        File_ShrinkName(dlgfilenames[i], tempstr, DLGFILENAMES_SIZE);
                    148:                        /* Mark folders: */
                    149:                        strcpy(tempstr, path);
                    150:                        strcat(tempstr, files[i+ypos]->d_name);
                    151: 
1.1.1.4   root      152:                        if (browsingzip)
1.1       root      153:                        {
1.1.1.3   root      154:                                if (File_DoesFileNameEndWithSlash(tempstr))
1.1       root      155:                                        dlgfilenames[i][0] = SGFOLDER;    /* Mark folders */
                    156:                        }
                    157:                        else
                    158:                        {
                    159:                                if( stat(tempstr, &filestat)==0 && S_ISDIR(filestat.st_mode) )
                    160:                                        dlgfilenames[i][0] = SGFOLDER;    /* Mark folders */
1.1.1.7   root      161:                                if (ZIP_FileNameIsZIP(tempstr) && browsingzip == false)
1.1       root      162:                                        dlgfilenames[i][0] = SGFOLDER;    /* Mark .ZIP archives as folders */
                    163:                        }
1.1.1.13! root      164: 
        !           165:                        fsdlg[SGFSDLG_ENTRYFIRST+i].flags |= SG_EXIT;
1.1       root      166:                }
                    167:                else
1.1.1.13! root      168:                {
1.1       root      169:                        dlgfilenames[i][0] = 0;  /* Clear entry */
1.1.1.13! root      170:                        fsdlg[SGFSDLG_ENTRYFIRST+i].flags &= ~SG_EXIT;
        !           171:                }
1.1       root      172:        }
                    173: 
                    174:        free(tempstr);
1.1.1.7   root      175:        return true;
1.1       root      176: }
                    177: 
                    178: 
                    179: /*-----------------------------------------------------------------------*/
1.1.1.8   root      180: /**
                    181:  * Remove all hidden files (files with file names that begin with a dot) from
                    182:  * the list.
                    183:  */
1.1.1.3   root      184: static void DlgFileSelect_RemoveHiddenFiles(struct dirent **files)
                    185: {
                    186:        int i;
                    187:        int nActPos = -1;
                    188:        int nOldEntries;
                    189: 
                    190:        nOldEntries = entries;
                    191: 
                    192:        /* Scan list for hidden files and remove them. */
                    193:        for (i = 0; i < nOldEntries; i++)
                    194:        {
                    195:                /* Does file name start with a dot? -> hidden file! */
                    196:                if (files[i]->d_name[0] == '.')
                    197:                {
                    198:                        if (nActPos == -1)
                    199:                                nActPos = i;
                    200:                        /* Remove file from list: */
                    201:                        free(files[i]);
                    202:                        files[i] = NULL;
                    203:                        entries -= 1;
                    204:                }
                    205:        }
                    206: 
                    207:        /* Now close the gaps in the list: */
                    208:        if (nActPos != -1)
                    209:        {
                    210:                for (i = nActPos; i < nOldEntries; i++)
                    211:                {
                    212:                        if (files[i] != NULL)
                    213:                        {
                    214:                                /* Move entry to earlier position: */
                    215:                                files[nActPos] = files[i];
                    216:                                files[i] = NULL;
                    217:                                nActPos += 1;
                    218:                        }
                    219:                }
                    220:        }
                    221: }
                    222: 
1.1.1.13! root      223: /**
        !           224:  * Reset focus to first entry if necessary.
        !           225:  */
        !           226: static void DlgFileSelect_ResetFocus(void)
        !           227: {
        !           228:        int i;
        !           229: 
        !           230:        for (i = SGFSDLG_ENTRYFIRST+1; i <= SGFSDLG_ENTRYLAST; i++)
        !           231:        {
        !           232:                if (fsdlg[i].state & SG_FOCUSED)
        !           233:                {
        !           234:                        fsdlg[i].state &= ~SG_FOCUSED;
        !           235:                        fsdlg[SGFSDLG_ENTRYFIRST].state |= SG_FOCUSED;
        !           236:                        break;
        !           237:                }
        !           238:        }
        !           239: }
1.1.1.3   root      240: 
                    241: /*-----------------------------------------------------------------------*/
1.1.1.8   root      242: /**
                    243:  * Prepare to scroll up one entry.
                    244:  */
1.1.1.2   root      245: static void DlgFileSelect_ScrollUp(void)
                    246: {
                    247:        if (ypos > 0)
                    248:        {
                    249:                --ypos;
1.1.1.9   root      250:                DlgFileSelect_Convert_ypos_to_scrollbar_Ypos();
1.1.1.7   root      251:                refreshentries = true;
1.1.1.2   root      252:        }
                    253: }
                    254: 
                    255: 
                    256: /*-----------------------------------------------------------------------*/
1.1.1.8   root      257: /**
                    258:  * Prepare to scroll down one entry.
                    259:  */
1.1.1.2   root      260: static void DlgFileSelect_ScrollDown(void)
                    261: {
                    262:        if (ypos+SGFS_NUMENTRIES < entries)
                    263:        {
                    264:                ++ypos;
1.1.1.9   root      265:                DlgFileSelect_Convert_ypos_to_scrollbar_Ypos();
1.1.1.7   root      266:                refreshentries = true;
1.1.1.2   root      267:        }
                    268: }
                    269: 
1.1.1.9   root      270: /*-----------------------------------------------------------------------*/
                    271: /**
                    272:  * Manage the scrollbar up or down.
                    273:  */
                    274: static void DlgFileSelect_ManageScrollbar(void)
                    275: {
                    276:        int b, x, y;
                    277:        int scrollY, scrollYmin, scrollYmax, scrollH_half;
                    278:        float scrollMove;
1.1.1.12  root      279: 
                    280:        SDL_GetMouseState(&x, &y);
1.1.1.9   root      281: 
                    282:        /* If mouse is down on the scrollbar for the first time */
                    283:        if (fsdlg[SGFSDLG_SCROLLBAR].state & SG_MOUSEDOWN) {
                    284:                if (mouseClicked == 0) {
                    285:                        mouseClicked = 1;
                    286:                        mouseIsOut = 0;
                    287:                        oldMouseY = y;
                    288:                }
                    289:        }
                    290:        /* Mouse button is up on the scrollbar */
                    291:        else {
                    292:                mouseClicked = 0;
                    293:                oldMouseY = y;
                    294:                mouseIsOut = 0;
                    295:        }
1.1.1.13! root      296: 
        !           297:        /* If mouse Y position didn't change */
1.1.1.9   root      298:        if (oldMouseY == y)
                    299:                return;
                    300: 
1.1.1.13! root      301:        /* Compute scrollbar ymin and ymax values */
1.1.1.9   root      302: 
                    303:        scrollYmin = (fsdlg[SGFSDLG_SCROLLBAR].y + fsdlg[0].y) * sdlgui_fontheight;
                    304:        scrollYmax = (fsdlg[SGFSDLG_DOWN].y + fsdlg[0].y) * sdlgui_fontheight;
1.1.1.13! root      305: 
1.1.1.9   root      306:        scrollY = fsdlg[SGFSDLG_SCROLLBAR].y * sdlgui_fontheight + fsdlg[SGFSDLG_SCROLLBAR].h + fsdlg[0].y * sdlgui_fontheight;
                    307:        scrollH_half = scrollY + fsdlg[SGFSDLG_SCROLLBAR].w / 2;
                    308:        scrollMove = (float)(y-oldMouseY)/sdlgui_fontheight;
1.1.1.13! root      309: 
1.1.1.9   root      310:        /* Verify if mouse is not above the scrollbar area */
                    311:        if (y < scrollYmin) {
                    312:                mouseIsOut = SCROLLOUT_ABOVE;
                    313:                oldMouseY = y;
                    314:                return;
                    315:        }
                    316:        if (mouseIsOut == SCROLLOUT_ABOVE && y < scrollH_half) {
                    317:                oldMouseY = y;
                    318:                return;
                    319:        }
                    320: 
                    321:        /* Verify if mouse is not under the scrollbar area */
                    322:        if (y > scrollYmax) {
                    323:                mouseIsOut = SCROLLOUT_UNDER;
                    324:                oldMouseY = y;
                    325:                return;
                    326:        }
                    327:        if (mouseIsOut == SCROLLOUT_UNDER && y > scrollH_half) {
                    328:                oldMouseY = y;
                    329:                return;
                    330:        }
                    331: 
                    332:        mouseIsOut = 0;
                    333: 
                    334:        scrollbar_Ypos += scrollMove;
                    335:        oldMouseY = y;
                    336: 
                    337:        /* Verifiy if scrollbar is in correct inferior boundary */
                    338:        if (scrollbar_Ypos < 0)
                    339:                scrollbar_Ypos = 0.0;
                    340: 
                    341:        /* Verifiy if scrollbar is in correct superior boundary */
                    342:        b = (int) (scrollbar_Ypos * ((float)entries/(float)(SGFS_NUMENTRIES-2)) + 0.5);
                    343:        if (b+SGFS_NUMENTRIES >= entries) {
                    344:                ypos = entries - SGFS_NUMENTRIES;
                    345:                DlgFileSelect_Convert_ypos_to_scrollbar_Ypos();
                    346:        }
                    347: 
1.1.1.13! root      348:        refreshentries = true;
1.1.1.9   root      349: }
1.1.1.2   root      350: 
                    351: /*-----------------------------------------------------------------------*/
1.1.1.8   root      352: /**
                    353:  * Handle SDL events.
                    354:  */
1.1.1.2   root      355: static void DlgFileSelect_HandleSdlEvents(SDL_Event *pEvent)
                    356: {
1.1.1.4   root      357:        int oldypos = ypos;
1.1.1.2   root      358:        switch (pEvent->type)
                    359:        {
1.1.1.13! root      360: #if WITH_SDL2
        !           361:         case SDL_MOUSEWHEEL:
        !           362:                if (pEvent->wheel.y>0)
        !           363:                        DlgFileSelect_ScrollUp();
        !           364:                else if (pEvent->wheel.y<0)
        !           365:                        DlgFileSelect_ScrollDown();
        !           366:                break;
        !           367: #else
1.1.1.2   root      368:         case SDL_MOUSEBUTTONDOWN:
                    369:                if (pEvent->button.button == SDL_BUTTON_WHEELUP)
                    370:                        DlgFileSelect_ScrollUp();
                    371:                else if (pEvent->button.button == SDL_BUTTON_WHEELDOWN)
                    372:                        DlgFileSelect_ScrollDown();
                    373:                break;
1.1.1.13! root      374: #endif
        !           375:         case SDL_KEYDOWN:
1.1.1.2   root      376:                switch (pEvent->key.keysym.sym)
                    377:                {
1.1.1.9   root      378:                 case SDLK_UP:
                    379:                        DlgFileSelect_ScrollUp();
                    380:                        break;
                    381:                 case SDLK_DOWN:
                    382:                        DlgFileSelect_ScrollDown();
                    383:                        break;
                    384:                 case SDLK_HOME:
1.1.1.13! root      385:                        ypos = 0;
1.1.1.9   root      386:                        DlgFileSelect_Convert_ypos_to_scrollbar_Ypos();
                    387:                        break;
                    388:                 case SDLK_END:
1.1.1.13! root      389:                    ypos = entries-SGFS_NUMENTRIES;
1.1.1.9   root      390:                        DlgFileSelect_Convert_ypos_to_scrollbar_Ypos();
                    391:                    break;
                    392:                 case SDLK_PAGEUP:
                    393:                    ypos -= SGFS_NUMENTRIES;
                    394:                        DlgFileSelect_Convert_ypos_to_scrollbar_Ypos();
                    395:                    break;
1.1.1.2   root      396:                 case SDLK_PAGEDOWN:
                    397:                        if (ypos+2*SGFS_NUMENTRIES < entries)
                    398:                                ypos += SGFS_NUMENTRIES;
                    399:                        else
                    400:                                ypos = entries-SGFS_NUMENTRIES;
1.1.1.9   root      401:                        DlgFileSelect_Convert_ypos_to_scrollbar_Ypos();
1.1.1.2   root      402:                        break;
1.1.1.4   root      403:                 default:
                    404:                        break;
1.1.1.2   root      405:                }
                    406:                break;
1.1.1.4   root      407:        default:
                    408:                break;
                    409:        }
1.1.1.13! root      410: 
1.1.1.9   root      411:        if (ypos < 0) {
1.1.1.4   root      412:                ypos = 0;
1.1.1.9   root      413:                scrollbar_Ypos = 0.0;
                    414:        }
1.1.1.13! root      415: 
1.1.1.4   root      416:        if (ypos != oldypos)
1.1.1.7   root      417:                refreshentries = true;
1.1.1.4   root      418: }
                    419: 
                    420: 
                    421: /*-----------------------------------------------------------------------*/
1.1.1.8   root      422: /**
                    423:  * Free file entries
                    424:  */
1.1.1.4   root      425: static struct dirent **files_free(struct dirent **files)
                    426: {
                    427:        int i;
                    428:        if (files != NULL)
                    429:        {
                    430:                for(i=0; i<entries; i++)
                    431:                {
                    432:                        free(files[i]);
                    433:                }
                    434:                free(files);
                    435:        }
                    436:        return NULL;
                    437: }
                    438: 
                    439: 
                    440: /*-----------------------------------------------------------------------*/
1.1.1.8   root      441: /**
                    442:  * Copy to dst src+add if they are below maxlen and return true,
                    443:  * otherwise return false
                    444:  */
1.1.1.4   root      445: static int strcat_maxlen(char *dst, int maxlen, const char *src, const char *add)
                    446: {
                    447:        int slen, alen;
                    448:        slen = strlen(src);
                    449:        alen = strlen(add);
                    450:        if (slen + alen < maxlen)
                    451:        {
                    452:                strcpy(dst, src);
                    453:                strcpy(dst+slen, add);
                    454:                return 1;
                    455:        }
                    456:        return 0;
                    457: }
                    458: 
                    459: /*-----------------------------------------------------------------------*/
1.1.1.8   root      460: /**
1.1.1.13! root      461:  * Get given file's type, directory or a file.
        !           462:  * (if name itself is symlink, stat() checks file it points to)
        !           463:  */
        !           464: static int get_dtype(const char *name)
        !           465: {
        !           466:        struct stat buf;
        !           467:        char path[FILENAME_MAX];
        !           468: 
        !           469:        snprintf(path, sizeof(path), "%s%c%s", dirpath, PATHSEP, name);
        !           470:        if (stat(path, &buf) == 0 && S_ISDIR(buf.st_mode))
        !           471:                return DT_DIR;
        !           472:        else
        !           473:                return DT_REG;
        !           474: }
        !           475: 
        !           476: /*-----------------------------------------------------------------------*/
        !           477: /**
        !           478:  * Case insensitive sorting for directory entry names, so
        !           479:  * that directory entries are listed first.
        !           480:  */
        !           481: static int filesort(const struct dirent **d1, const struct dirent **d2)
        !           482: {
        !           483:        const char *name1 = (*d1)->d_name;
        !           484:        const char *name2 = (*d2)->d_name;
        !           485: #ifndef HAVE_DIRENT_D_TYPE
        !           486:        int type1 = DT_UNKNOWN;
        !           487:        int type2 = DT_UNKNOWN;
        !           488: #else
        !           489:        int type1 = (*d1)->d_type;
        !           490:        int type2 = (*d2)->d_type;
        !           491: #endif
        !           492: 
        !           493:        /* OS / file system that doesn't support d_type field, or symlink */
        !           494:        if (type1 == DT_UNKNOWN || type1 == DT_LNK)
        !           495:                type1 = get_dtype(name1);
        !           496:        if (type2 == DT_UNKNOWN || type2 == DT_LNK)
        !           497:                type2 = get_dtype(name2);
        !           498: 
        !           499:        if (type1 == DT_DIR)
        !           500:        {
        !           501:                if (type2 != DT_DIR)
        !           502:                        return -1;
        !           503:        } else if (type2 == DT_DIR)
        !           504:        {
        !           505:                if (type1 != DT_DIR)
        !           506:                        return 1;
        !           507:        }
        !           508:        return strcasecmp(name1, name2);
        !           509: }
        !           510: 
        !           511: /*-----------------------------------------------------------------------*/
        !           512: /**
1.1.1.8   root      513:  * Create and return suitable path into zip file
                    514:  */
1.1.1.4   root      515: static char* zip_get_path(const char *zipdir, const char *zipfilename, int browsingzip)
                    516: {
                    517:        if (browsingzip)
                    518:        {
                    519:                char *zippath;
                    520:                zippath = malloc(strlen(zipdir) + strlen(zipfilename) + 1);
                    521:                strcpy(zippath, zipdir);
                    522:                strcat(zippath, zipfilename);
                    523:                return zippath;
1.1.1.2   root      524:        }
1.1.1.4   root      525:        return strdup("");
1.1.1.2   root      526: }
                    527: 
1.1.1.8   root      528: /**
                    529:  * string for zip root needs to be empty, check and correct if needed
                    530:  */
1.1.1.4   root      531: static void correct_zip_root(char *zippath)
                    532: {
                    533:        if (zippath[0] == PATHSEP && !zippath[1])
                    534:        {
                    535:                zippath[0] = '\0';
                    536:        }
                    537: }
1.1.1.2   root      538: 
1.1.1.9   root      539: /**
                    540:  * Convert Ypos to Y scrollbar position
                    541:  */
                    542: static void DlgFileSelect_Convert_ypos_to_scrollbar_Ypos(void)
                    543: {
                    544:        if (entries <= SGFS_NUMENTRIES)
                    545:                scrollbar_Ypos = 0.0;
                    546:        else
                    547:                scrollbar_Ypos = (float)ypos / ((float)entries/(float)(SGFS_NUMENTRIES-2));
                    548: }
                    549: 
1.1.1.2   root      550: /*-----------------------------------------------------------------------*/
1.1.1.8   root      551: /**
                    552:  * Show and process a file selection dialog.
                    553:  * Returns path/name user selected or NULL if user canceled
                    554:  * input: zip_path = pointer's pointer to buffer to contain file path
                    555:  * within a selected zip file, or NULL if browsing zip files is disallowed.
                    556:  * bAllowNew: true if the user is allowed to insert new file names.
                    557:  */
1.1.1.13! root      558: char* SDLGui_FileSelect(const char *title, const char *path_and_name, char **zip_path, bool bAllowNew)
1.1       root      559: {
                    560:        struct dirent **files = NULL;
                    561:        char *pStringMem;
1.1.1.10  root      562:        char *retpath = NULL;
1.1.1.8   root      563:        const char *home;
                    564:        char *path, *fname;                 /* The actual file and path names */
1.1.1.7   root      565:        bool reloaddir = true;              /* Do we have to reload the directory file list? */
1.1.1.13! root      566:        int retbut, len;
1.1.1.10  root      567:        bool bOldMouseVisibility;
1.1.1.9   root      568:        int selection;                      /* The selection index */
1.1       root      569:        char *zipfilename;                  /* Filename in zip file */
                    570:        char *zipdir;
1.1.1.7   root      571:        bool browsingzip = false;           /* Are we browsing an archive? */
1.1       root      572:        zip_dir *zipfiles = NULL;
1.1.1.2   root      573:        SDL_Event sdlEvent;
1.1.1.13! root      574:        int yScrollbar_size;                /* Size of the vertical scrollbar */
        !           575:        union {
        !           576:                char *mtxt;
        !           577:                const char *ctxt;
        !           578:        } dlgtitle;                         /* A hack to silent recent GCCs warnings */
        !           579:        bool KeepCurrentObject;
        !           580: 
        !           581:        dlgtitle.ctxt = title;
1.1.1.11  root      582: 
                    583:        /* If this is the first call to SDLGui_FileSelect, we reset scrollbar_Ypos and ypos */
                    584:        /* Else, we keep the previous value of scrollbar_Ypos and update ypos below, to open */
                    585:        /* the fileselector at the same position it was used */
                    586:        if ( ypos < 0 )
                    587:        {
                    588:                scrollbar_Ypos = 0.0;
                    589:                ypos = 0;
                    590:        }
1.1.1.2   root      591: 
1.1.1.7   root      592:        refreshentries = true;
1.1.1.2   root      593:        entries = 0;
1.1       root      594: 
                    595:        /* Allocate memory for the file and path name strings: */
                    596:        pStringMem = malloc(4 * FILENAME_MAX);
                    597:        path = pStringMem;
                    598:        fname = pStringMem + FILENAME_MAX;
1.1.1.4   root      599:        zipdir = pStringMem + 2 * FILENAME_MAX;
                    600:        zipfilename = pStringMem + 3 * FILENAME_MAX;
1.1       root      601:        zipfilename[0] = 0;
1.1.1.5   root      602:        fname[0] = 0;
                    603:        path[0] = 0;
1.1       root      604: 
1.1.1.13! root      605:        len = strlen(title);
        !           606:        fsdlg[SGFSDLG_TITLE].txt = dlgtitle.mtxt;
        !           607:        fsdlg[SGFSDLG_TITLE].x = TITLE_OFFSET + (TITLE_MAXLEN-len)/2;
        !           608:        fsdlg[SGFSDLG_TITLE].w = len;
        !           609: 
1.1.1.10  root      610:        /* Save mouse state and enable cursor */
                    611:        bOldMouseVisibility = SDL_ShowCursor(SDL_QUERY);
                    612:        SDL_ShowCursor(SDL_ENABLE);
                    613: 
1.1       root      614:        SDLGui_CenterDlg(fsdlg);
                    615:        if (bAllowNew)
                    616:        {
                    617:                fsdlg[SGFSDLG_FILENAME].type = SGEDITFIELD;
                    618:                fsdlg[SGFSDLG_FILENAME].flags |= SG_EXIT;
                    619:        }
                    620:        else
                    621:        {
                    622:                fsdlg[SGFSDLG_FILENAME].type = SGTEXT;
                    623:                fsdlg[SGFSDLG_FILENAME].flags &= ~SG_EXIT;
                    624:        }
                    625: 
                    626:        /* Prepare the path and filename variables */
1.1.1.4   root      627:        if (path_and_name && path_and_name[0])
1.1.1.2   root      628:        {
1.1.1.4   root      629:                strncpy(path, path_and_name, FILENAME_MAX);
                    630:                path[FILENAME_MAX-1] = '\0';
                    631:        }
1.1.1.5   root      632:        if (!File_DirExists(path))
1.1.1.4   root      633:        {
1.1.1.5   root      634:                File_SplitPath(path, path, fname, NULL);
                    635:                if (!(File_DirExists(path) || getcwd(path, FILENAME_MAX)))
1.1.1.4   root      636:                {
1.1.1.5   root      637:                        perror("SDLGui_FileSelect: non-existing path and CWD failed");
1.1.1.10  root      638:                        goto clean_exit;
1.1.1.4   root      639:                }
1.1.1.2   root      640:        }
1.1.1.5   root      641: 
1.1.1.2   root      642:        File_MakeAbsoluteName(path);
                    643:        File_MakeValidPathName(path);
1.1       root      644:        File_ShrinkName(dlgpath, path, DLGPATH_SIZE);
                    645:        File_ShrinkName(dlgfname, fname, DLGFNAME_SIZE);
                    646: 
1.1.1.13! root      647:        /* The first time we display the dialog, we reset the current position */
        !           648:        /* On next calls, current_object's value will be kept to handle scrolling */
        !           649:        KeepCurrentObject = false;
        !           650: 
1.1       root      651:        do
                    652:        {
                    653:                if (reloaddir)
                    654:                {
1.1.1.4   root      655:                        files = files_free(files);
1.1       root      656: 
                    657:                        if (browsingzip)
                    658:                        {
                    659:                                files = ZIP_GetFilesDir(zipfiles, zipdir, &entries);
1.1.1.8   root      660:                                if(!files)
                    661:                                {
                    662:                                        fprintf(stderr, "SDLGui_FileSelect: ZIP_GetFilesDir error!\n");
1.1.1.10  root      663:                                        goto clean_exit;
1.1.1.8   root      664:                                }
1.1       root      665:                        }
                    666:                        else
                    667:                        {
1.1.1.13! root      668:                                /* for get_dtype() */
        !           669:                                dirpath = path;
1.1       root      670:                                /* Load directory entries: */
1.1.1.13! root      671:                                entries = scandir(path, &files, NULL, filesort);
1.1       root      672:                        }
1.1.1.13! root      673: 
1.1.1.3   root      674:                        /* Remove hidden files from the list if necessary: */
                    675:                        if (!(fsdlg[SGFSDLG_SHOWHIDDEN].state & SG_SELECTED))
                    676:                        {
                    677:                                DlgFileSelect_RemoveHiddenFiles(files);
                    678:                        }
1.1       root      679: 
                    680:                        if (entries < 0)
                    681:                        {
                    682:                                fprintf(stderr, "SDLGui_FileSelect: Path not found.\n");
1.1.1.10  root      683:                                goto clean_exit;
1.1       root      684:                        }
                    685: 
1.1.1.4   root      686:                        /* reload always implies refresh */
1.1.1.7   root      687:                        reloaddir = false;
                    688:                        refreshentries = true;
1.1.1.13! root      689: 
        !           690:                        /* Check if focus was in list - if yes then reset to first entry */
        !           691:                        DlgFileSelect_ResetFocus();
1.1       root      692:                }/* reloaddir */
                    693: 
1.1.1.9   root      694:                /* Refresh scrollbar size */
1.1.1.13! root      695:                if (entries <= SGFS_NUMENTRIES)
1.1.1.11  root      696:                        yScrollbar_size = (SGFS_NUMENTRIES-2) * sdlgui_fontheight;
1.1.1.9   root      697:                else
1.1.1.11  root      698:                {
                    699:                        yScrollbar_size = (int)((SGFS_NUMENTRIES-2) / ((float)entries/(float)SGFS_NUMENTRIES) * sdlgui_fontheight);
                    700:                        if ( yScrollbar_size < SCROLLBAR_MIN_HEIGHT )           /* Value could be 0 for very large directory */
                    701:                                yScrollbar_size = SCROLLBAR_MIN_HEIGHT;
                    702:                }
                    703:                fsdlg[SGFSDLG_SCROLLBAR].w = yScrollbar_size;
                    704: 
1.1.1.9   root      705:                /* Refresh scrolbar pos */
                    706:                ypos = (int) (scrollbar_Ypos * ((float)entries/(float)(SGFS_NUMENTRIES-2)) + 0.5);
1.1.1.11  root      707: 
                    708:                if (ypos+SGFS_NUMENTRIES >= entries) {                  /* Ensure Y pos is in the correct boundaries */
                    709:                        ypos = entries - SGFS_NUMENTRIES;
                    710:                        if ( ypos < 0 )
                    711:                                ypos = 0;
                    712:                        DlgFileSelect_Convert_ypos_to_scrollbar_Ypos();
                    713:                }
                    714:                fsdlg[SGFSDLG_SCROLLBAR].h = (int) (scrollbar_Ypos * sdlgui_fontheight);
                    715: 
1.1       root      716:                /* Update the file name strings in the dialog? */
                    717:                if (refreshentries)
                    718:                {
1.1.1.2   root      719:                        if (!DlgFileSelect_RefreshEntries(files, path, browsingzip))
1.1       root      720:                        {
1.1.1.10  root      721:                                goto clean_exit;
1.1       root      722:                        }
1.1.1.7   root      723:                        refreshentries = false;
1.1       root      724:                }
                    725: 
                    726:                /* Show dialog: */
1.1.1.13! root      727:                retbut = SDLGui_DoDialog(fsdlg, &sdlEvent, KeepCurrentObject);
        !           728:                KeepCurrentObject = true;                               /* Don't reset current_object for next calls */
1.1       root      729: 
                    730:                /* Has the user clicked on a file or folder? */
1.1.1.9   root      731:                if (retbut>=SGFSDLG_ENTRYFIRST && retbut<=SGFSDLG_ENTRYLAST && retbut-SGFSDLG_ENTRYFIRST+ypos<entries)
1.1       root      732:                {
                    733:                        char *tempstr;
1.1.1.13! root      734: 
1.1       root      735:                        tempstr = malloc(FILENAME_MAX);
                    736:                        if (!tempstr)
                    737:                        {
                    738:                                perror("Error while allocating temporary memory in SDLGui_FileSelect()");
1.1.1.10  root      739:                                goto clean_exit;
1.1       root      740:                        }
                    741: 
1.1.1.7   root      742:                        if (browsingzip == true)
1.1       root      743:                        {
1.1.1.4   root      744:                                if (!strcat_maxlen(tempstr, FILENAME_MAX,
1.1.1.9   root      745:                                                   zipdir, files[retbut-SGFSDLG_ENTRYFIRST+ypos]->d_name))
1.1.1.4   root      746:                                {
                    747:                                        fprintf(stderr, "SDLGui_FileSelect: Path name too long!\n");
1.1.1.12  root      748:                                        free(tempstr);
1.1.1.10  root      749:                                        goto clean_exit;
1.1.1.4   root      750:                                }
                    751:                                /* directory? */
1.1.1.3   root      752:                                if (File_DoesFileNameEndWithSlash(tempstr))
1.1       root      753:                                {
                    754:                                        /* handle the ../ directory */
1.1.1.9   root      755:                                        if (strcmp(files[retbut-SGFSDLG_ENTRYFIRST+ypos]->d_name, "../") == 0)
1.1       root      756:                                        {
                    757:                                                /* close the zip file */
1.1.1.4   root      758:                                                if (strcmp(tempstr, "../") == 0)
1.1       root      759:                                                {
                    760:                                                        /* free zip file entries */
                    761:                                                        ZIP_FreeZipDir(zipfiles);
                    762:                                                        zipfiles = NULL;
                    763:                                                        /* Copy the path name to the dialog */
                    764:                                                        File_ShrinkName(dlgpath, path, DLGPATH_SIZE);
1.1.1.7   root      765:                                                        browsingzip = false;
1.1       root      766:                                                }
                    767:                                                else
                    768:                                                {
1.1.1.4   root      769:                                                        /* remove "../" and previous dir from path */
                    770:                                                        File_PathShorten(tempstr, 2);
                    771:                                                        correct_zip_root(tempstr);
1.1       root      772:                                                        strcpy(zipdir, tempstr);
                    773:                                                        File_ShrinkName(dlgpath, zipdir, DLGPATH_SIZE);
                    774:                                                }
                    775:                                        }
                    776:                                        else /* not the "../" directory */
                    777:                                        {
                    778:                                                strcpy(zipdir, tempstr);
                    779:                                                File_ShrinkName(dlgpath, zipdir, DLGPATH_SIZE);
                    780:                                        }
1.1.1.7   root      781:                                        reloaddir = true;
1.1       root      782:                                        /* Copy the path name to the dialog */
                    783:                                        zipfilename[0] = '\0';
                    784:                                        dlgfname[0] = 0;
                    785:                                        ypos = 0;
1.1.1.9   root      786:                                        scrollbar_Ypos = 0.0;
1.1       root      787:                                }
                    788:                                else
                    789:                                {
1.1.1.4   root      790:                                        /* not dir, select a file in the zip */
1.1.1.9   root      791:                                        selection = retbut-SGFSDLG_ENTRYFIRST+ypos;
1.1       root      792:                                        strcpy(zipfilename, files[selection]->d_name);
                    793:                                        File_ShrinkName(dlgfname, zipfilename, DLGFNAME_SIZE);
                    794:                                }
                    795: 
1.1.1.4   root      796:                        }
                    797:                        else /* not browsingzip */
1.1       root      798:                        {
1.1.1.4   root      799:                                if (!strcat_maxlen(tempstr, FILENAME_MAX,
1.1.1.9   root      800:                                                   path, files[retbut-SGFSDLG_ENTRYFIRST+ypos]->d_name))
1.1       root      801:                                {
1.1.1.4   root      802:                                        fprintf(stderr, "SDLGui_FileSelect: Path name too long!\n");
1.1.1.12  root      803:                                        free(tempstr);
1.1.1.10  root      804:                                        goto clean_exit;
1.1.1.4   root      805:                                }
1.1.1.5   root      806:                                if (File_DirExists(tempstr))
1.1.1.4   root      807:                                {
                    808:                                        File_HandleDotDirs(tempstr);
                    809:                                        File_AddSlashToEndFileName(tempstr);
                    810:                                        /* Copy the path name to the dialog */
                    811:                                        File_ShrinkName(dlgpath, tempstr, DLGPATH_SIZE);
1.1       root      812:                                        strcpy(path, tempstr);
1.1.1.7   root      813:                                        reloaddir = true;
1.1       root      814:                                        dlgfname[0] = 0;
                    815:                                        ypos = 0;
1.1.1.9   root      816:                                        scrollbar_Ypos = 0.0;
1.1       root      817:                                }
                    818:                                else if (ZIP_FileNameIsZIP(tempstr) && zip_path != NULL)
                    819:                                {
                    820:                                        /* open a zip file */
                    821:                                        zipfiles = ZIP_GetFiles(tempstr);
1.1.1.7   root      822:                                        if (zipfiles != NULL && browsingzip == false)
1.1       root      823:                                        {
1.1.1.9   root      824:                                                selection = retbut-SGFSDLG_ENTRYFIRST+ypos;
1.1       root      825:                                                strcpy(fname, files[selection]->d_name);
                    826:                                                File_ShrinkName(dlgfname, fname, DLGFNAME_SIZE);
1.1.1.7   root      827:                                                browsingzip = true;
1.1.1.4   root      828:                                                zipdir[0] = '\0'; /* zip root */
1.1       root      829:                                                File_ShrinkName(dlgpath, zipdir, DLGPATH_SIZE);
1.1.1.7   root      830:                                                reloaddir = true;
1.1       root      831:                                                ypos = 0;
1.1.1.9   root      832:                                                scrollbar_Ypos = 0.0;
1.1       root      833:                                        }
                    834: 
                    835:                                }
                    836:                                else
                    837:                                {
                    838:                                        /* Select a file */
1.1.1.9   root      839:                                        selection = retbut-SGFSDLG_ENTRYFIRST+ypos;
1.1       root      840:                                        strcpy(fname, files[selection]->d_name);
                    841:                                        File_ShrinkName(dlgfname, fname, DLGFNAME_SIZE);
                    842:                                }
                    843: 
                    844:                        } /* not browsingzip */
                    845: 
                    846:                        free(tempstr);
                    847:                }
                    848:                else    /* Has the user clicked on another button? */
                    849:                {
                    850:                        switch(retbut)
                    851:                        {
                    852:                        case SGFSDLG_UPDIR:                 /* Change path to parent directory */
1.1.1.4   root      853:                                if (browsingzip)
1.1       root      854:                                {
1.1.1.4   root      855:                                        /* close the zip file? */
                    856:                                        if (!zipdir[0])
1.1       root      857:                                        {
                    858:                                                /* free zip file entries */
                    859:                                                ZIP_FreeZipDir(zipfiles);
1.1.1.7   root      860:                                                browsingzip = false;
1.1       root      861:                                                zipfiles = NULL;
                    862:                                                File_ShrinkName(dlgpath, path, DLGPATH_SIZE);
                    863:                                        }
                    864:                                        else
                    865:                                        {
1.1.1.4   root      866:                                                /* remove last dir from zipdir path */
                    867:                                                File_PathShorten(zipdir, 1);
                    868:                                                correct_zip_root(zipdir);
1.1       root      869:                                                File_ShrinkName(dlgpath, zipdir, DLGPATH_SIZE);
                    870:                                                zipfilename[0] = '\0';
                    871:                                        }
                    872:                                }  /* not a zip file: */
1.1.1.4   root      873:                                else
1.1       root      874:                                {
1.1.1.4   root      875:                                        File_PathShorten(path, 1);
                    876:                                        File_ShrinkName(dlgpath, path, DLGPATH_SIZE);
1.1       root      877:                                }
1.1.1.7   root      878:                                reloaddir = true;
1.1       root      879:                                break;
1.1.1.3   root      880: 
                    881:                        case SGFSDLG_HOMEDIR:               /* Change to home directory */
1.1.1.11  root      882:                        case SGFSDLG_CWD:                   /* Change to current work directory */
                    883:                                if (retbut == SGFSDLG_CWD)
                    884:                                        home = Paths_GetWorkingDir();
                    885:                                else
                    886:                                        home = Paths_GetUserHome();
1.1.1.8   root      887:                                if (home == NULL || !*home)
1.1.1.3   root      888:                                        break;
                    889:                                if (browsingzip)
                    890:                                {
                    891:                                        /* free zip file entries */
                    892:                                        ZIP_FreeZipDir(zipfiles);
                    893:                                        zipfiles = NULL;
1.1.1.7   root      894:                                        browsingzip = false;
1.1.1.3   root      895:                                }
1.1.1.4   root      896:                                strcpy(path, home);
1.1.1.3   root      897:                                File_AddSlashToEndFileName(path);
1.1.1.4   root      898:                                File_ShrinkName(dlgpath, path, DLGPATH_SIZE);
1.1.1.7   root      899:                                reloaddir = true;
1.1.1.3   root      900:                                break;
                    901: 
1.1       root      902:                        case SGFSDLG_ROOTDIR:               /* Change to root directory */
1.1.1.4   root      903:                                if (browsingzip)
1.1       root      904:                                {
                    905:                                        /* free zip file entries */
                    906:                                        ZIP_FreeZipDir(zipfiles);
                    907:                                        zipfiles = NULL;
1.1.1.7   root      908:                                        browsingzip = false;
1.1       root      909:                                }
1.1.1.7   root      910:                                path[0] = PATHSEP; path[1] = '\0';
1.1       root      911:                                strcpy(dlgpath, path);
1.1.1.7   root      912:                                reloaddir = true;
1.1       root      913:                                break;
                    914:                        case SGFSDLG_UP:                    /* Scroll up */
1.1.1.2   root      915:                                DlgFileSelect_ScrollUp();
                    916:                                SDL_Delay(10);
1.1       root      917:                                break;
                    918:                        case SGFSDLG_DOWN:                  /* Scroll down */
1.1.1.2   root      919:                                DlgFileSelect_ScrollDown();
                    920:                                SDL_Delay(10);
1.1       root      921:                                break;
1.1.1.9   root      922:                        case SGFSDLG_SCROLLBAR:             /* Scrollbar selected */
                    923:                                DlgFileSelect_ManageScrollbar();
                    924:                                SDL_Delay(10);
                    925:                                break;
1.1       root      926:                        case SGFSDLG_FILENAME:              /* User entered new filename */
                    927:                                strcpy(fname, dlgfname);
                    928:                                break;
1.1.1.3   root      929:                        case SGFSDLG_SHOWHIDDEN:            /* Show/hide hidden files */
1.1.1.7   root      930:                                reloaddir = true;
1.1.1.3   root      931:                                ypos = 0;
1.1.1.9   root      932:                                scrollbar_Ypos = 0.0;
1.1.1.3   root      933:                                break;
1.1.1.2   root      934:                        case SDLGUI_UNKNOWNEVENT:
                    935:                                DlgFileSelect_HandleSdlEvents(&sdlEvent);
                    936:                                break;
1.1       root      937:                        } /* switch */
1.1.1.13! root      938: 
1.1.1.4   root      939:                        if (reloaddir)
                    940:                        {
                    941:                                /* Remove old selection */
                    942:                                fname[0] = 0;
                    943:                                dlgfname[0] = 0;
                    944:                                ypos = 0;
1.1.1.9   root      945:                                scrollbar_Ypos = 0.0;
1.1.1.4   root      946:                        }
1.1       root      947:                } /* other button code */
                    948: 
                    949: 
                    950:        } /* do */
1.1.1.4   root      951:        while (retbut!=SGFSDLG_OKAY && retbut!=SGFSDLG_CANCEL
                    952:               && retbut!=SDLGUI_QUIT && retbut != SDLGUI_ERROR && !bQuitProgram);
1.1       root      953: 
1.1.1.4   root      954:        if (retbut == SGFSDLG_OKAY)
1.1       root      955:        {
1.1.1.4   root      956:                if (zip_path)
                    957:                        *zip_path = zip_get_path(zipdir, zipfilename, browsingzip);
                    958:                retpath = File_MakePath(path, fname, NULL);
                    959:        }
                    960:        else
                    961:                retpath = NULL;
1.1.1.13! root      962: 
1.1.1.10  root      963: clean_exit:
                    964:        SDL_ShowCursor(bOldMouseVisibility);
1.1.1.13! root      965: 
        !           966:        if (browsingzip && zipfiles != NULL)
        !           967:        {
        !           968:                /* free zip file entries */
        !           969:                ZIP_FreeZipDir(zipfiles);
        !           970:                zipfiles = NULL;
        !           971:        }
        !           972:        files_free(files);
1.1.1.4   root      973:        free(pStringMem);
1.1.1.13! root      974: 
1.1.1.4   root      975:        return retpath;
                    976: }
                    977: 
                    978: 
                    979: /*-----------------------------------------------------------------------*/
1.1.1.8   root      980: /**
                    981:  * Let user browse for a file, confname is used as default.
1.1.1.4   root      982:  * If bAllowNew is true, user can select new files also.
1.1.1.13! root      983:  *
1.1.1.4   root      984:  * If no file is selected, or there's some problem with the file,
1.1.1.7   root      985:  * return false and clear dlgname & confname.
                    986:  * Otherwise return true, set dlgname & confname to the new file name
1.1.1.11  root      987:  * (dlgname is shrunken & limited to maxlen and confname is assumed
1.1.1.4   root      988:  * to have FILENAME_MAX amount of space).
                    989:  */
1.1.1.13! root      990: bool SDLGui_FileConfSelect(const char *title, char *dlgname, char *confname, int maxlen, bool bAllowNew)
1.1.1.4   root      991: {
                    992:        char *selname;
1.1.1.13! root      993: 
        !           994:        selname = SDLGui_FileSelect(title, confname, NULL, bAllowNew);
1.1.1.4   root      995:        if (selname)
                    996:        {
                    997:                if (!File_DoesFileNameEndWithSlash(selname) &&
                    998:                    (bAllowNew || File_Exists(selname)))
1.1       root      999:                {
1.1.1.4   root     1000:                        strncpy(confname, selname, FILENAME_MAX);
                   1001:                        confname[FILENAME_MAX-1] = '\0';
                   1002:                        File_ShrinkName(dlgname, selname, maxlen);
1.1       root     1003:                }
                   1004:                else
1.1.1.4   root     1005:                {
                   1006:                        dlgname[0] = confname[0] = 0;
                   1007:                }
                   1008:                free(selname);
1.1.1.7   root     1009:                return true;
1.1       root     1010:        }
1.1.1.7   root     1011:        return false;
1.1       root     1012: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.