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