diff options
| author | Manolo Gouy <Manolo> | 2016-04-07 15:10:30 +0000 |
|---|---|---|
| committer | Manolo Gouy <Manolo> | 2016-04-07 15:10:30 +0000 |
| commit | 23a60edb44d264887a398eef1b6346f8f24737e2 (patch) | |
| tree | ae6920a8b002dd26240f560d61df84888ba3b4a5 /src/drivers | |
| parent | 406fcaf3053b2d8d9c8ea677c59667a7ec43a556 (diff) | |
Rewrite filename_list.cxx under the driver model.
One more platform-dependent type is necessary: struct dirent
Create a new header file, FL/platform_types.h, to define all
types whose definition is platform-dependent.
This file is for C because it is included by scandir_XXX.c
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11550 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/drivers')
| -rw-r--r-- | src/drivers/Darwin/Fl_Darwin_System_Driver.H | 1 | ||||
| -rw-r--r-- | src/drivers/Darwin/Fl_Darwin_System_Driver.cxx | 47 | ||||
| -rw-r--r-- | src/drivers/Posix/Fl_Posix_System_Driver.H | 1 | ||||
| -rw-r--r-- | src/drivers/Posix/Fl_Posix_System_Driver.cxx | 85 | ||||
| -rw-r--r-- | src/drivers/WinAPI/Fl_WinAPI_System_Driver.H | 1 | ||||
| -rw-r--r-- | src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx | 13 |
6 files changed, 147 insertions, 1 deletions
diff --git a/src/drivers/Darwin/Fl_Darwin_System_Driver.H b/src/drivers/Darwin/Fl_Darwin_System_Driver.H index 442dcd687..0803f32d5 100644 --- a/src/drivers/Darwin/Fl_Darwin_System_Driver.H +++ b/src/drivers/Darwin/Fl_Darwin_System_Driver.H @@ -68,6 +68,7 @@ public: // these 2 are in Fl_get_key_mac.cxx virtual int event_key(int k); virtual int get_key(int k); + virtual int filename_list(const char *d, dirent ***list, int (*sort)(struct dirent **, struct dirent **) ); }; #endif // FL_DARWIN_SYSTEM_DRIVER_H diff --git a/src/drivers/Darwin/Fl_Darwin_System_Driver.cxx b/src/drivers/Darwin/Fl_Darwin_System_Driver.cxx index 2f6d52fc6..617e8b19d 100644 --- a/src/drivers/Darwin/Fl_Darwin_System_Driver.cxx +++ b/src/drivers/Darwin/Fl_Darwin_System_Driver.cxx @@ -20,6 +20,7 @@ #include "../../config_lib.h" #include "Fl_Darwin_System_Driver.H" #include <FL/Fl.H> +#include <FL/filename.H> #include <string.h> #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 #include <xlocale.h> @@ -88,6 +89,52 @@ void *Fl_Darwin_System_Driver::get_carbon_function(const char *function_name) { return (carbon ? dlsym(carbon, function_name) : NULL); } +int Fl_Darwin_System_Driver::filename_list(const char *d, dirent ***list, int (*sort)(struct dirent **, struct dirent **) ) { + int dirlen; + char *dirloc; + // Assume that locale encoding is no less dense than UTF-8 + dirlen = strlen(d); + dirloc = (char *)d; +# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8 + int n = scandir(dirloc, list, 0, (int(*)(const struct dirent**,const struct dirent**))sort); +# else + int n = scandir(dirloc, list, 0, (int(*)(const void*,const void*))sort); +# endif + // convert every filename to utf-8, and append a '/' to all + // filenames that are directories + int i; + char *fullname = (char*)malloc(dirlen+FL_PATH_MAX+3); // Add enough extra for two /'s and a nul + // Use memcpy for speed since we already know the length of the string... + memcpy(fullname, d, dirlen+1); + char *name = fullname + dirlen; + if (name!=fullname && name[-1]!='/') *name++ = '/'; + for (i=0; i<n; i++) { + int newlen; + dirent *de = (*list)[i]; + int len = strlen(de->d_name); + newlen = len; + dirent *newde = (dirent*)malloc(de->d_name - (char*)de + newlen + 2); // Add space for a / and a nul + // Conversion to UTF-8 + memcpy(newde, de, de->d_name - (char*)de); + strcpy(newde->d_name, de->d_name); + // Check if dir (checks done on "old" name as we need to interact with + // the underlying OS) + if (de->d_name[len-1]!='/' && len<=FL_PATH_MAX) { + // Use memcpy for speed since we already know the length of the string... + memcpy(name, de->d_name, len+1); + if (fl_filename_isdir(fullname)) { + char *dst = newde->d_name + newlen; + *dst++ = '/'; + *dst = 0; + } + } + free(de); + (*list)[i] = newde; + } + free(fullname); + return n; +} + // // End of "$Id$". // diff --git a/src/drivers/Posix/Fl_Posix_System_Driver.H b/src/drivers/Posix/Fl_Posix_System_Driver.H index 1c8042e3f..aa922d590 100644 --- a/src/drivers/Posix/Fl_Posix_System_Driver.H +++ b/src/drivers/Posix/Fl_Posix_System_Driver.H @@ -65,6 +65,7 @@ public: // these 2 are in Fl_get_key.cxx virtual int event_key(int k); virtual int get_key(int k); + virtual int filename_list(const char *d, dirent ***list, int (*sort)(struct dirent **, struct dirent **) ); }; #endif // FL_POSIX_SYSTEM_DRIVER_H diff --git a/src/drivers/Posix/Fl_Posix_System_Driver.cxx b/src/drivers/Posix/Fl_Posix_System_Driver.cxx index dffedeb93..6ce92675f 100644 --- a/src/drivers/Posix/Fl_Posix_System_Driver.cxx +++ b/src/drivers/Posix/Fl_Posix_System_Driver.cxx @@ -16,8 +16,9 @@ // http://www.fltk.org/str.php // - +#include <config.h> #include "Fl_Posix_System_Driver.H" +#include <FL/filename.H> #include <FL/Fl.H> #include <X11/Xlib.h> #include <locale.h> @@ -30,6 +31,14 @@ const char* fl_local_ctrl = "Ctrl"; const char* fl_local_meta = "Meta"; const char* fl_local_shift = "Shift"; +#ifndef HAVE_SCANDIR +extern "C" { + int fl_scandir(const char *dirname, struct dirent ***namelist, + int (*select)(struct dirent *), + int (*compar)(struct dirent **, struct dirent **)); +} +#endif + /** Creates a driver that manages all screen and display related calls. @@ -57,6 +66,80 @@ int Fl_Posix_System_Driver::clocale_printf(FILE *output, const char *format, va_ return retval; } +int Fl_Posix_System_Driver::filename_list(const char *d, dirent ***list, int (*sort)(struct dirent **, struct dirent **) ) { + int dirlen; + char *dirloc; + + // Assume that locale encoding is no less dense than UTF-8 + dirlen = strlen(d); + dirloc = (char *)malloc(dirlen + 1); + fl_utf8to_mb(d, dirlen, dirloc, dirlen + 1); + +#ifndef HAVE_SCANDIR + // This version is when we define our own scandir + int n = fl_scandir(dirloc, list, 0, sort); +#elif defined(HAVE_SCANDIR_POSIX) + // POSIX (2008) defines the comparison function like this: + int n = scandir(dirloc, list, 0, (int(*)(const dirent **, const dirent **))sort); +#elif defined(__osf__) + // OSF, DU 4.0x + int n = scandir(dirloc, list, 0, (int(*)(dirent **, dirent **))sort); +#elif defined(_AIX) + // AIX is almost standard... + int n = scandir(dirloc, list, 0, (int(*)(void*, void*))sort); +#elif defined(__sgi) + int n = scandir(dirloc, list, 0, sort); +#else + // The vast majority of UNIX systems want the sort function to have this + // prototype, most likely so that it can be passed to qsort without any + // changes: + int n = scandir(dirloc, list, 0, (int(*)(const void*,const void*))sort); +#endif + + free(dirloc); + + // convert every filename to utf-8, and append a '/' to all + // filenames that are directories + int i; + char *fullname = (char*)malloc(dirlen+FL_PATH_MAX+3); // Add enough extra for two /'s and a nul + // Use memcpy for speed since we already know the length of the string... + memcpy(fullname, d, dirlen+1); + + char *name = fullname + dirlen; + if (name!=fullname && name[-1]!='/') + *name++ = '/'; + + for (i=0; i<n; i++) { + int newlen; + dirent *de = (*list)[i]; + int len = strlen(de->d_name); + newlen = fl_utf8from_mb(NULL, 0, de->d_name, len); + dirent *newde = (dirent*)malloc(de->d_name - (char*)de + newlen + 2); // Add space for a / and a nul + + // Conversion to UTF-8 + memcpy(newde, de, de->d_name - (char*)de); + fl_utf8from_mb(newde->d_name, newlen + 1, de->d_name, len); + + // Check if dir (checks done on "old" name as we need to interact with + // the underlying OS) + if (de->d_name[len-1]!='/' && len<=FL_PATH_MAX) { + // Use memcpy for speed since we already know the length of the string... + memcpy(name, de->d_name, len+1); + if (fl_filename_isdir(fullname)) { + char *dst = newde->d_name + newlen; + *dst++ = '/'; + *dst = 0; + } + } + + free(de); + (*list)[i] = newde; + } + free(fullname); + + return n; +} + // // End of "$Id$". // diff --git a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H index bb903f00a..ccf51aec0 100644 --- a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H +++ b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H @@ -68,6 +68,7 @@ public: // these 2 are in Fl_get_key_win32.cxx virtual int event_key(int k); virtual int get_key(int k); + virtual int filename_list(const char *d, dirent ***list, int (*sort)(struct dirent **, struct dirent **) ); }; #endif // FL_WINAPI_SYSTEM_DRIVER_H diff --git a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx index 46bd9dc78..9a0c25d4d 100644 --- a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx +++ b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx @@ -39,6 +39,12 @@ static wchar_t *mbwbuf = NULL; static wchar_t *wbuf = NULL; static wchar_t *wbuf1 = NULL; +extern "C" { + int fl_scandir(const char *dirname, struct dirent ***namelist, + int (*select)(struct dirent *), + int (*compar)(struct dirent **, struct dirent **)); +} + /** Creates a driver that manages all screen and display related calls. @@ -429,6 +435,13 @@ int Fl_WinAPI_System_Driver::clocale_printf(FILE *output, const char *format, va return retval; } +int Fl_WinAPI_System_Driver::filename_list(const char *d, dirent ***list, int (*sort)(struct dirent **, struct dirent **) ) { + // For Windows we have a special scandir implementation that uses + // the Win32 "wide" functions for lookup, avoiding the code page mess + // entirely. It also fixes up the trailing '/'. + return fl_scandir(d, list, 0, sort); +} + // // End of "$Id$". // |
