summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
authorManolo Gouy <Manolo>2016-04-07 15:10:30 +0000
committerManolo Gouy <Manolo>2016-04-07 15:10:30 +0000
commit23a60edb44d264887a398eef1b6346f8f24737e2 (patch)
treeae6920a8b002dd26240f560d61df84888ba3b4a5 /src/drivers
parent406fcaf3053b2d8d9c8ea677c59667a7ec43a556 (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.H1
-rw-r--r--src/drivers/Darwin/Fl_Darwin_System_Driver.cxx47
-rw-r--r--src/drivers/Posix/Fl_Posix_System_Driver.H1
-rw-r--r--src/drivers/Posix/Fl_Posix_System_Driver.cxx85
-rw-r--r--src/drivers/WinAPI/Fl_WinAPI_System_Driver.H1
-rw-r--r--src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx13
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$".
//