Author: bgbnbigben
Date: 2011-01-29 00:49:42 -0800 (Sat, 29 Jan 2011)
New Revision: 8328
Log:
Fixed the second half of STR #1637 (see SVN r8317). This makes the win32 
filechooser correctly read unicode filenames.
This required the addition of a new fltk_stat() function, in an effort to make 
all calls to stat() more portable and unicode aware.


Modified:
   trunk/fltk/filename.h
   trunk/src/FileIcon.cxx
   trunk/src/filename_isdir.cxx
   trunk/src/win32/scandir.c

Modified: trunk/fltk/filename.h
===================================================================
--- trunk/fltk/filename.h       2011-01-29 06:00:46 UTC (rev 8327)
+++ trunk/fltk/filename.h       2011-01-29 08:49:42 UTC (rev 8328)
@@ -26,9 +26,16 @@
 #define fltk_filename_h
 
 #include "FL_API.h"
+#include <sys/types.h>
+#include <sys/stat.h>
 
 ////////////////////////////////////////////////////////////////
 #ifndef DOXYGEN
+
+#if defined (_WIN32) && !defined (__CYGWIN__)
+# define stat _stat
+#endif
+
 // dirent (what a pain)...
 
 // FC: UNDER WIN32/VC6 long long is undefined, so use __int64 instead
@@ -102,6 +109,7 @@
 /// Some functions to manipulate filenames, to make portable programs.
 //@{
 
+FL_API int fltk_stat(const char* name, struct stat *buffer);
 FL_API int filename_absolute(char *to, int tolen, const char *from, const 
char* cwd=0);
 FL_API int filename_relative(char *to, int tolen, const char *from, const 
char* cwd=0);
 FL_API const char *filename_name(const char *);

Modified: trunk/src/FileIcon.cxx
===================================================================
--- trunk/src/FileIcon.cxx      2011-01-29 06:00:46 UTC (rev 8327)
+++ trunk/src/FileIcon.cxx      2011-01-29 08:49:42 UTC (rev 8328)
@@ -40,6 +40,7 @@
 #include <fltk/string.h>
 #include <fltk/Item.h>
 #include <fltk/Browser.h>
+#include <fltk/utf.h>
 #include <ctype.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -215,10 +216,9 @@
   FileIcon     *current;               // Current file in list
   struct stat  fileinfo;               // Information on file
 
-
   // Get file information if needed...
   if (filetype == ANY)
-    if (!stat(filename, &fileinfo))
+    if (!fltk_stat(filename, &fileinfo))
     {
       if (S_ISDIR(fileinfo.st_mode))
        filetype = DIRECTORY;

Modified: trunk/src/filename_isdir.cxx
===================================================================
--- trunk/src/filename_isdir.cxx        2011-01-29 06:00:46 UTC (rev 8327)
+++ trunk/src/filename_isdir.cxx        2011-01-29 08:49:42 UTC (rev 8328)
@@ -26,6 +26,7 @@
 #include <config.h>
 #include <fltk/filename.h>
 #include <fltk/string.h>
+#include <fltk/utf.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #if defined(_WIN32) && !defined(__CYGWIN__)
@@ -41,6 +42,25 @@
 static const char *last_statname = 0;
 static bool last_result = false;
 
+/** Portably calls the system's stat() function, to deal with UTF-8 
+    and UTF-16 filenames.
+    Has the same return values and use as the system's stat.
+*/
+int fltk::fltk_stat(const char* name, struct stat *buffer) {
+#if defined(_WIN32) && !defined (__CYGWIN__)
+  wchar_t * nativeFilename = NULL;
+  int length = utf8towc(name, strlen(name), NULL, 0);
+  nativeFilename = new wchar_t[length+2];
+  utf8towc(name, strlen(name), nativeFilename, length+1);
+  int ret = _wstat(nativeFilename, buffer);
+  delete [] nativeFilename;
+#else
+  int ret = stat(nativeFilename, buffer);
+#endif
+  return ret;
+}
+
+
 static bool fill_stat(const char *name) {
   if (last_statname && strcmp(last_statname, name)==0) return last_result;
   delete[] const_cast<char *>( last_statname ); // otherwize VC++ will scream
@@ -55,8 +75,10 @@
     buffer[3] = 0;
     name = buffer;
   }
-#endif // _WIN32 || __EMX__
-  last_result = (stat(name, &last_stat)==0);
+  // on _WIN32 && !__CYGWIN__, all strings into this file will be UTF-8
+
+#endif// _WIN32 || __EMX__
+  last_result = (fltk::fltk_stat(name, &last_stat)==0);
   return last_result;
 }
 

Modified: trunk/src/win32/scandir.c
===================================================================
--- trunk/src/win32/scandir.c   2011-01-29 06:00:46 UTC (rev 8327)
+++ trunk/src/win32/scandir.c   2011-01-29 08:49:42 UTC (rev 8328)
@@ -22,7 +22,6 @@
 // Emulation of posix scandir() call
 // This source file is #include'd by scandir.c
 // THIS IS A C FILE! DO NOT CHANGE TO C++!!!
-
 #include <string.h>
 #include <windows.h>
 #include <stdlib.h>
@@ -41,22 +40,40 @@
 int scandir(const char *dirname, struct dirent ***namelist,
     int (*select)(struct dirent *),
     int (*compar)(struct dirent **, struct dirent **)) {
-  char *d;
-  WIN32_FIND_DATA find;
+  WIN32_FIND_DATAW find;
   HANDLE h;
-  int nDir = 0, NDir = 0;
+  int nDir = 0, NDir = 0, len;
   struct dirent **dir = 0, *selectDir;
   unsigned long ret;
-  char findIn[MAX_PATH];
+  char *findIn, *d, *temp;
+  unsigned widelen;
+  unsigned short* widebuff = NULL;
 
-  strlcpy ( findIn, dirname, MAX_PATH );
+  len = strlen(dirname);
+  findIn = (char*)malloc(len+10);
+
+  if(!findIn) return -1;
+  strcpy(findIn, dirname);
+
   d = findIn+strlen(findIn);
   if (d==findIn) *d++ = '.';
   if (*(d-1)!='/' && *(d-1)!='\\') *d++ = '/';
   *d++ = '*';
   *d++ = 0;
+ 
 
-  if ((h=FindFirstFile(findIn, &find))==INVALID_HANDLE_VALUE) {
+  // Change the filename to a wchar_t* representation
+  // so we can read unicode filenames (if any exist)
+  widelen = utf8frommb(NULL, 0, findIn, strlen(findIn));
+  temp = (char*)malloc(sizeof(char)*widelen+2);
+  utf8frommb(temp, widelen+1, findIn, strlen(findIn));
+  widelen = utf8towc(temp, widelen, NULL, 0);
+  widebuff = (unsigned short*)malloc(sizeof(unsigned short)*widelen+2);
+  utf8towc(temp, strlen(temp), widebuff, widelen+1);
+  free(temp);
+  free(findIn);
+
+  if ((h=FindFirstFileW(widebuff, &find))==INVALID_HANDLE_VALUE) {
     ret = GetLastError();
     if (ret != ERROR_NO_MORE_FILES) {
       // TODO: return some error code
@@ -64,9 +81,11 @@
     *namelist = dir;
     return nDir;
   }
+  free(widebuff);
   do {
-    selectDir=(struct dirent*)malloc(sizeof(struct 
dirent)+strlen(find.cFileName));
-    strcpy(selectDir->d_name, find.cFileName);
+    selectDir=(struct dirent*)malloc(sizeof(struct 
dirent)+wcslen(find.cFileName)*5+1);
+       // convert the filename back to UTF-8, as this is what FLTK uses 
internally
+       utf8fromwc(selectDir->d_name, sizeof(struct 
dirent)+wcslen(find.cFileName)*5+1, find.cFileName, wcslen(find.cFileName));
     if (!select || (*select)(selectDir)) {
       if (nDir==NDir) {
        struct dirent **tempDir = (struct dirent **)calloc(sizeof(struct 
dirent*), NDir+33);
@@ -81,7 +100,7 @@
     } else {
       free(selectDir);
     }
-  } while (FindNextFile(h, &find));
+  } while (FindNextFileW(h, &find));
   ret = GetLastError();
   if (ret != ERROR_NO_MORE_FILES) {
     // TODO: return some error code

_______________________________________________
fltk-commit mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-commit

Reply via email to