2.5のマルチバイトパス対策パッチ
とりあえずできた。
外部とのアクセスの前後でutf8とローカルの文字コードとを変換するようにした。FindFirstFile, FindNextFile, stat, chdir, gzopenあたりのファイルパスを引数に取る関数や、SHGetSpecialFolderPathなどのパスを返す関数が対象。
内部をutf8で統一して出入り口を押さえるのがいいと思う。もう少しバージョンが進んで外部フォント指定のインターフェースが公開されたら送ってみようかな。
Index: blender/blenkernel/intern/exotic.c =================================================================== --- blender/blenkernel/intern/exotic.c (revision 27274) +++ blender/blenkernel/intern/exotic.c (working copy) @@ -1777,6 +1777,9 @@ } +#ifdef WIN32 +#include <windows.h> +#endif int BKE_read_exotic(Scene *scene, char *name) { ListBase lbase={0, 0}; @@ -1790,6 +1793,18 @@ len= strlen(name); if (name[len-1] !='/' && name[len-1] != '\\') { +#ifdef WIN32 + { + // utf8 to local encoding + wchar_t unicode[MAX_PATH]; + char oem[MAX_PATH]; + int size; + size=MultiByteToWideChar(CP_UTF8, 0, name, -1, unicode, MAX_PATH); + size=WideCharToMultiByte(CP_OEMCP, 0, unicode, size, + oem, MAX_PATH, 0, NULL); + strcpy(name, oem); + } +#endif gzfile = gzopen(name,"rb"); if (NULL == gzfile ) { Index: blender/blenlib/BLI_winstuff.h =================================================================== --- blender/blenlib/BLI_winstuff.h (revision 27274) +++ blender/blenlib/BLI_winstuff.h (working copy) @@ -86,7 +86,7 @@ #define write _write #define read _read #define getcwd _getcwd -#define chdir _chdir +//#define chdir _chdir #define strdup _strdup #define lseek _lseek #define getpid _getpid @@ -115,8 +115,8 @@ typedef struct _DIR { HANDLE handle; - WIN32_FIND_DATA data; - char path[MAX_PATH]; + WIN32_FIND_DATAW data; + wchar_t path[MAX_PATH]; long dd_loc; long dd_size; char dd_buf[4096]; @@ -132,6 +132,8 @@ void get_default_root(char *root); int check_file_chars(char *filename); char *dirname(char *path); +int BLI_chdir(const char *dirname); +int BLI_stat(const char *path, struct _stat64 *buf); #ifdef WIN32 int BLI_getInstallationDir(char *str); Index: blender/blenlib/intern/storage.c =================================================================== --- blender/blenlib/intern/storage.c (revision 27274) +++ blender/blenlib/intern/storage.c (working copy) @@ -80,6 +80,8 @@ #include <io.h> #include <direct.h> #include "BLI_winstuff.h" +//#include <shlwapi.h> +#pragma comment(lib, "shlwapi") #endif @@ -228,7 +230,11 @@ rellen++; } +#ifdef WIN32 + if (BLI_chdir(dirname) == -1){ +#else if (chdir(dirname) == -1){ +#endif perror(dirname); return; } @@ -264,11 +270,13 @@ files[actnum].path = BLI_strdupcat(dirname, dlink->name); // use 64 bit file size, only needed for WIN32 and WIN64. // Excluding other than current MSVC compiler until able to test. -#if (defined(WIN32) || defined(WIN64)) && (_MSC_VER>=1500) - _stat64(dlink->name,&files[actnum].s); +// move to winstuff +#ifdef WIN32 + BLI_stat(dlink->name,&files[actnum].s); #else stat(dlink->name,&files[actnum].s); #endif + files[actnum].type=files[actnum].s.st_mode; files[actnum].flags = 0; totnum++; @@ -449,25 +457,16 @@ return size; } - +#ifndef WIN32 int BLI_exist(char *name) { struct stat st; -#ifdef WIN32 - /* in Windows stat doesn't recognize dir ending on a slash - To not break code where the ending slash is expected we - don't mess with the argument name directly here - elubie */ - char tmp[FILE_MAXDIR+FILE_MAXFILE]; - int len; - BLI_strncpy(tmp, name, FILE_MAXDIR+FILE_MAXFILE); - len = strlen(tmp); - if (len > 3 && ( tmp[len-1]=='\\' || tmp[len-1]=='/') ) tmp[len-1] = '\0'; - if (stat(tmp,&st)) return(0); -#else - if (stat(name,&st)) return(0); -#endif + if (stat(name,&st)){ + return(0); + } return(st.st_mode); } +#endif /* would be better in fileops.c except that it needs stat.h so add here */ int BLI_is_dir(char *file) { Index: blender/blenlib/intern/winstuff.c =================================================================== --- blender/blenlib/intern/winstuff.c (revision 27274) +++ blender/blenlib/intern/winstuff.c (working copy) @@ -28,6 +28,8 @@ * Windows-posix compatibility layer, windows-specific functions. */ +#include <shlwapi.h> + #ifdef HAVE_CONFIG_H #include <config.h> #endif @@ -98,22 +100,33 @@ DIR *opendir (const char *path) { if (GetFileAttributes(path) & FILE_ATTRIBUTE_DIRECTORY) { + int size; + DIR *newd= MEM_mallocN(sizeof(DIR), "opendir"); newd->handle = INVALID_HANDLE_VALUE; - sprintf(newd->path, "%s\\*",path); - + size=MultiByteToWideChar(CP_UTF8, 0, path, -1, newd->path, MAX_PATH); + newd->path[size-1]=L'\\'; + newd->path[size]=L'*'; + newd->path[size+1]=0; newd->direntry.d_ino= 0; newd->direntry.d_off= 0; newd->direntry.d_reclen= 0; newd->direntry.d_name= NULL; - + return newd; } else { return NULL; } } +static char* BLI_strdup_wide2utf8(const wchar_t *unicode) { + char utf8[MAX_PATH*2]; + int size; + size=WideCharToMultiByte(CP_UTF8, 0, unicode, -1, utf8, MAX_PATH*2, 0, NULL); + return BLI_strdup(utf8); +} + struct dirent *readdir(DIR *dp) { if (dp->direntry.d_name) { MEM_freeN(dp->direntry.d_name); @@ -121,15 +134,15 @@ } if (dp->handle==INVALID_HANDLE_VALUE) { - dp->handle= FindFirstFile(dp->path, &(dp->data)); + dp->handle= FindFirstFileW(dp->path, &(dp->data)); if (dp->handle==INVALID_HANDLE_VALUE) return NULL; - dp->direntry.d_name= BLI_strdup(dp->data.cFileName); + dp->direntry.d_name= BLI_strdup_wide2utf8(dp->data.cFileName); return &dp->direntry; - } else if (FindNextFile (dp->handle, &(dp->data))) { - dp->direntry.d_name= BLI_strdup(dp->data.cFileName); + } else if (FindNextFileW(dp->handle, &(dp->data))) { + dp->direntry.d_name= BLI_strdup_wide2utf8(dp->data.cFileName); return &dp->direntry; } else { @@ -243,6 +256,46 @@ } /* End of copied part */ +#include <sys/stat.h> +int BLI_stat(const char *path, struct _stat64 *buf) +{ + wchar_t unicode[MAX_PATH]; + int size; + size=MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, + path, -1, unicode, MAX_PATH); + return _wstat64(unicode, buf); +} + +#include <direct.h> +int BLI_chdir(const char *path) +{ + wchar_t unicode[MAX_PATH]; + int size; + size=MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, + path, -1, unicode, MAX_PATH); + return _wchdir(unicode); +} + +int BLI_exist(char *name) +{ + wchar_t unicode[MAX_PATH]; + int size; + struct _stat64 st; + size=MultiByteToWideChar(CP_UTF8, 0, name, -1, unicode, MAX_PATH); + if(size==4 && unicode[1]==L':'){ + // C:/, D:/... + } + else if(size>3 && unicode[size-2]==0x005c){ // '\\' + unicode[size-2]=0x0000; + } + + if(_wstat64(unicode, &st)){ + return 0; + } + return st.st_mode; +} + + #else /* intentionally empty for UNIX */ Index: blender/blenfont/intern/blf.c =================================================================== --- blender/blenfont/intern/blf.c (revision 27274) +++ blender/blenfont/intern/blf.c (working copy) @@ -298,7 +298,7 @@ global_font_default= blf_search("default"); if (global_font_default == -1) { - printf("Warning: Can't found default font!!\n"); + //printf("Warning: Can't found default font!!\n"); return; } Index: blender/editors/space_file/fsmenu.c =================================================================== --- blender/editors/space_file/fsmenu.c (revision 27274) +++ blender/editors/space_file/fsmenu.c (working copy) @@ -258,7 +258,9 @@ /* Add the drive names to the listing */ { __int64 tmp; - char folder[256]; + wchar_t unicode[256]; + char folder[1024]; + int size; char tmps[4]; int i; @@ -276,9 +278,12 @@ } /* Adding Desktop and My Documents */ - SHGetSpecialFolderPath(0, folder, CSIDL_PERSONAL, 0); + SHGetSpecialFolderPathW(0, unicode, CSIDL_PERSONAL, 0); + size=WideCharToMultiByte(CP_UTF8, 0, unicode, -1, folder, 1024, 0, NULL); fsmenu_insert_entry(fsmenu,FS_CATEGORY_BOOKMARKS, folder, 1, 0); - SHGetSpecialFolderPath(0, folder, CSIDL_DESKTOPDIRECTORY, 0); + + SHGetSpecialFolderPathW(0, unicode, CSIDL_DESKTOPDIRECTORY, 0); + size=WideCharToMultiByte(CP_UTF8, 0, unicode, -1, folder, 1024, 0, NULL); fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, folder, 1, 0); } #else Index: blender/editors/interface/interface_style.c =================================================================== --- blender/editors/interface/interface_style.c (revision 27274) +++ blender/editors/interface/interface_style.c (working copy) @@ -270,14 +270,18 @@ /* recover from uninitialized dpi */ CLAMP(U.dpi, 72, 240); - + /* default builtin */ if(font==NULL) { font= MEM_callocN(sizeof(uiFont), "ui font"); BLI_addtail(&U.uifonts, font); - + /* strcpy(font->filename, "default"); font->uifont_id= UIFONT_DEFAULT; + */ + strcpy(font->filename, "msgothic.ttc"); + font->uifont_id= UIFONT_CUSTOM1; + BLF_dir_add("C:/WINDOWS/Fonts"); } for(font= U.uifonts.first; font; font= font->next) {