/**************************************************************************** * libwiigui Template * Tantric 2009 * * modified by dimok * * filebrowser.cpp * * Generic file routines - reading, writing, browsing ***************************************************************************/ #include #include #include #include #include #include #include #include "filebrowser.h" #include "menu.h" BROWSERINFO browser; BROWSERENTRY * browserList = NULL; // list of files/folders in browser /**************************************************************************** * ResetBrowser() * Clears the file browser memory, and allocates one initial entry ***************************************************************************/ void ResetBrowser() { browser.numEntries = 0; browser.selIndex = 0; browser.pageIndex = 0; // Clear any existing values if(browserList != NULL) { free(browserList); browserList = NULL; } // set aside space for 1 entry browserList = (BROWSERENTRY *)malloc(sizeof(BROWSERENTRY)); memset(browserList, 0, sizeof(BROWSERENTRY)); } /**************************************************************************** * UpdateDirName() * Update curent directory name for file browser ***************************************************************************/ int UpdateDirName() { int size=0; char * test; char temp[1024]; /* current directory doesn't change */ if (strcmp(browserList[browser.selIndex].filename,".") == 0) { return 0; } /* go up to parent directory */ else if (strcmp(browserList[browser.selIndex].filename,"..") == 0) { /* determine last subdirectory namelength */ sprintf(temp,"%s",browser.dir); test = strtok(temp,"/"); while (test != NULL) { size = strlen(test); test = strtok(NULL,"/"); } /* remove last subdirectory name */ size = strlen(browser.dir) - size - 1; browser.dir[size] = 0; return 1; } /* Open a directory */ else { /* test new directory namelength */ if ((strlen(browser.dir)+1+strlen(browserList[browser.selIndex].filename)) < MAXPATHLEN) { /* update current directory name */ sprintf(browser.dir, "%s/%s",browser.dir, browserList[browser.selIndex].filename); return 1; } else { return -1; } } } /**************************************************************************** * FileSortCallback * * Quick sort callback to sort file entries with the following order: * . * .. * * ***************************************************************************/ int FileSortCallback(const void *f1, const void *f2) { /* Special case for implicit directories */ if(((BROWSERENTRY *)f1)->filename[0] == '.' || ((BROWSERENTRY *)f2)->filename[0] == '.') { if(strcmp(((BROWSERENTRY *)f1)->filename, ".") == 0) { return -1; } if(strcmp(((BROWSERENTRY *)f2)->filename, ".") == 0) { return 1; } if(strcmp(((BROWSERENTRY *)f1)->filename, "..") == 0) { return -1; } if(strcmp(((BROWSERENTRY *)f2)->filename, "..") == 0) { return 1; } } /* If one is a file and one is a directory the directory is first. */ if(((BROWSERENTRY *)f1)->isdir && !(((BROWSERENTRY *)f2)->isdir)) return -1; if(!(((BROWSERENTRY *)f1)->isdir) && ((BROWSERENTRY *)f2)->isdir) return 1; return stricmp(((BROWSERENTRY *)f1)->filename, ((BROWSERENTRY *)f2)->filename); } /*************************************************************************** * Browse subdirectories **************************************************************************/ int ParseDirectory() { DIR_ITER *dir = NULL; char fulldir[MAXPATHLEN]; char filename[MAXPATHLEN]; struct stat filestat; // reset browser ResetBrowser(); // open the directory sprintf(fulldir, "%s%s", browser.rootdir, browser.dir); // add currentDevice to path dir = diropen(fulldir); // if we can't open the dir, try opening the root dir if (dir == NULL) { sprintf(browser.dir,"/"); dir = diropen(browser.rootdir); if (dir == NULL) { return -1; } } // index files/folders int entryNum = 0; while(dirnext(dir,filename,&filestat) == 0) { if(strcmp(filename,".") != 0) { BROWSERENTRY * newBrowserList = (BROWSERENTRY *)realloc(browserList, (entryNum+1) * sizeof(BROWSERENTRY)); if(!newBrowserList) // failed to allocate required memory { ResetBrowser(); entryNum = -1; break; } else { browserList = newBrowserList; } memset(&(browserList[entryNum]), 0, sizeof(BROWSERENTRY)); // clear the new entry strncpy(browserList[entryNum].filename, filename, MAXJOLIET); if(strcmp(filename,"..") == 0) { sprintf(browserList[entryNum].displayname, ".."); } else { strcpy(browserList[entryNum].displayname, filename); // crop name for display } browserList[entryNum].length = filestat.st_size; browserList[entryNum].isdir = (filestat.st_mode & _IFDIR) == 0 ? 0 : 1; // flag this as a dir entryNum++; } } // close directory dirclose(dir); // Sort the file list qsort(browserList, entryNum, sizeof(BROWSERENTRY), FileSortCallback); browser.numEntries = entryNum; return entryNum; } /**************************************************************************** * BrowserChangeFolder * * Update current directory and set new entry list if directory has changed ***************************************************************************/ int BrowserChangeFolder() { if(!UpdateDirName()) return -1; ParseDirectory(); return browser.numEntries; } /**************************************************************************** * BrowseDevice * Displays a list of files on the selected device ***************************************************************************/ int BrowseDevice(int device) { sprintf(browser.dir, "/"); switch(device) { case SD: sprintf(browser.rootdir, "SD:"); break; case USB: sprintf(browser.rootdir, "USB:"); break; } ParseDirectory(); // Parse root directory return browser.numEntries; }