diff options
author | Alexander Kuznetsov <kuzsasha@gmail.com> | 2012-03-20 06:17:37 +0400 |
---|---|---|
committer | Alexander Kuznetsov <kuzsasha@gmail.com> | 2012-03-20 06:17:37 +0400 |
commit | f11a6d3a847e8e18faefd8694373d2f11b5ec802 (patch) | |
tree | b4bec6dcfd28e3da4fa1e84ee4bd20fa0a21be39 | |
parent | deea1f38b1ec0ccba283abeb63506cbc15e093d5 (diff) |
Adds support for utf paths on Windows.
Not all file formats/calls are supported yet. It will be expended.
Please from now on use BLI_fopen, BLI_* for file manipulations.
For non-windows systems BLI_fopen just calls fopen.
For Windows, the utf-8 string is translated to utf-16 string in order to call UTF version of the function.
66 files changed, 1012 insertions, 175 deletions
diff --git a/build_files/scons/tools/Blender.py b/build_files/scons/tools/Blender.py index d806b14deea..155b4e800bb 100644 --- a/build_files/scons/tools/Blender.py +++ b/build_files/scons/tools/Blender.py @@ -340,6 +340,7 @@ def creator(env): if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): incs.append(env['BF_PTHREADS_INC']) + incs.append('#/intern/utfconv') env.Append(CPPDEFINES=defs) env.Append(CPPPATH=incs) diff --git a/intern/CMakeLists.txt b/intern/CMakeLists.txt index 9f5217e68e3..5637fa383a1 100644 --- a/intern/CMakeLists.txt +++ b/intern/CMakeLists.txt @@ -66,3 +66,8 @@ if(WITH_CYCLES) add_subdirectory(cycles) endif() + +#Only Windows needs utf16 converter +if(WIN32) + add_subdirectory(utfconv) +endif()
\ No newline at end of file diff --git a/intern/SConscript b/intern/SConscript index bb19426263a..196a80433c9 100644 --- a/intern/SConscript +++ b/intern/SConscript @@ -3,6 +3,7 @@ Import ('env') SConscript(['audaspace/SConscript', 'string/SConscript', + 'utfconv/SConscript', 'ghost/SConscript', 'guardedalloc/SConscript', 'moto/SConscript', diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt index 5693aea0865..5c653ac92c0 100644 --- a/intern/ghost/CMakeLists.txt +++ b/intern/ghost/CMakeLists.txt @@ -281,6 +281,10 @@ elseif(WIN32) ${WINTAB_INC} ) + list(APPEND INC + ../utfconv + ) + list(APPEND SRC intern/GHOST_DisplayManagerWin32.cpp intern/GHOST_SystemWin32.cpp diff --git a/intern/ghost/SConscript b/intern/ghost/SConscript index 3410f11a971..2265daa8fff 100644 --- a/intern/ghost/SConscript +++ b/intern/ghost/SConscript @@ -110,6 +110,7 @@ else: if window_system in ('win32-vc', 'win32-mingw', 'cygwin', 'linuxcross', 'win64-vc'): incs = env['BF_WINTAB_INC'] + ' ' + incs + incs += ' ../utfconv' if window_system in ('win32-vc', 'win64-vc'): env.BlenderLib ('bf_intern_ghost', sources, Split(incs), defines=defs, libtype=['intern','player'], priority = [40,15]) #, cc_compileflags=env['CCFLAGS'].append('/WX') ) diff --git a/intern/ghost/intern/GHOST_DropTargetWin32.cpp b/intern/ghost/intern/GHOST_DropTargetWin32.cpp index 4c9072d2ce6..c13c242bc7e 100644 --- a/intern/ghost/intern/GHOST_DropTargetWin32.cpp +++ b/intern/ghost/intern/GHOST_DropTargetWin32.cpp @@ -34,6 +34,9 @@ #include "GHOST_DropTargetWin32.h" #include <ShellApi.h> +#include "utf_winfunc.h" +#include "utfconv.h" + #ifdef GHOST_DEBUG // utility void printLastError(void); @@ -267,20 +270,12 @@ void * GHOST_DropTargetWin32::getDropDataAsFilenames(IDataObject * pDataObject) { if ( ::DragQueryFileW ( hdrop, nfile, fpath, MAX_PATH ) > 0 ) { - if ( !WideCharToANSI(fpath, temp_path) ) + if ( !(temp_path = alloc_utf_8_from_16(fpath, 0)) ) { continue; } // Just ignore paths that could not be converted verbatim. - if (strpbrk(temp_path, "?")) - { -#ifdef GHOST_DEBUG - ::printf("\ndiscarding path that contains illegal characters: %s", temp_path); -#endif // GHOST_DEBUG - ::free(temp_path); - temp_path = NULL; - continue; - } + strArray->strings[nvalid] = (GHOST_TUns8*) temp_path; strArray->count = nvalid+1; nvalid++; @@ -309,7 +304,7 @@ void * GHOST_DropTargetWin32::getDropDataAsString(IDataObject * pDataObject) if(pDataObject->GetData(&fmtetc, &stgmed) == S_OK) { LPCWSTR wstr = (LPCWSTR)::GlobalLock(stgmed.hGlobal); - if ( !WideCharToANSI(wstr, tmp_string) ) + if ( !(tmp_string = alloc_utf_8_from_16((wchar_t*)wstr, 0)) ) { ::GlobalUnlock(stgmed.hGlobal); return NULL; diff --git a/intern/ghost/intern/GHOST_SystemPathsWin32.cpp b/intern/ghost/intern/GHOST_SystemPathsWin32.cpp index 379e1963c40..29c2e9c0227 100644 --- a/intern/ghost/intern/GHOST_SystemPathsWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemPathsWin32.cpp @@ -35,6 +35,7 @@ #define _WIN32_IE 0x0501 #endif #include <shlobj.h> +#include "utfconv.h" #if defined(__MINGW32__) || defined(__CYGWIN__) @@ -70,11 +71,14 @@ GHOST_SystemPathsWin32::~GHOST_SystemPathsWin32() const GHOST_TUns8* GHOST_SystemPathsWin32::getSystemDir() const { - static char knownpath[MAX_PATH]; - HRESULT hResult = SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, SHGFP_TYPE_CURRENT, knownpath); + static char knownpath[MAX_PATH*3] = {0}; /* 1 utf-16 might translante into 3 utf-8. 2 utf-16 translates into 4 utf-8*/ + wchar_t knownpath_16[MAX_PATH]; + + HRESULT hResult = SHGetFolderPathW(NULL, CSIDL_COMMON_APPDATA, NULL, SHGFP_TYPE_CURRENT, knownpath_16); if (hResult == S_OK) { + conv_utf_16_to_8(knownpath_16,knownpath,MAX_PATH*3); return (GHOST_TUns8*)knownpath; } @@ -83,11 +87,14 @@ const GHOST_TUns8* GHOST_SystemPathsWin32::getSystemDir() const const GHOST_TUns8* GHOST_SystemPathsWin32::getUserDir() const { - static char knownpath[MAX_PATH]; - HRESULT hResult = SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, knownpath); + static char knownpath[MAX_PATH*3] = {0}; + wchar_t knownpath_16[MAX_PATH]; + + HRESULT hResult = SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, knownpath_16); if (hResult == S_OK) { + conv_utf_16_to_8(knownpath_16,knownpath,MAX_PATH*3); return (GHOST_TUns8*)knownpath; } @@ -96,8 +103,11 @@ const GHOST_TUns8* GHOST_SystemPathsWin32::getUserDir() const const GHOST_TUns8* GHOST_SystemPathsWin32::getBinaryDir() const { - static char fullname[MAX_PATH]; - if(GetModuleFileName(0, fullname, MAX_PATH)) { + static char fullname[MAX_PATH*3] = {0}; + wchar_t fullname_16[MAX_PATH*3]; + + if(GetModuleFileNameW(0, fullname_16, MAX_PATH)) { + conv_utf_16_to_8(fullname_16,fullname,MAX_PATH*3); return (GHOST_TUns8*)fullname; } @@ -107,5 +117,7 @@ const GHOST_TUns8* GHOST_SystemPathsWin32::getBinaryDir() const void GHOST_SystemPathsWin32::addToSystemRecentFiles(const char* filename) const { /* SHARD_PATH resolves to SHARD_PATHA for non-UNICODE build */ - SHAddToRecentDocs(SHARD_PATH,filename); + UTF16_ENCODE(filename) + SHAddToRecentDocs(SHARD_PATHW,filename_16); + UTF16_UN_ENCODE(filename) } diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index b478fea706c..b79185b1637 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -60,6 +60,8 @@ #endif #endif +#include "utfconv.h" + #include "GHOST_DisplayManagerWin32.h" #include "GHOST_EventButton.h" #include "GHOST_EventCursor.h" @@ -292,8 +294,8 @@ bool GHOST_SystemWin32::processEvents(bool waitForEvent) } // Process all the events waiting for us - while (::PeekMessage(&msg, 0, 0, 0, PM_REMOVE) != 0) { - ::DispatchMessage(&msg); + while (::PeekMessageW(&msg, 0, 0, 0, PM_REMOVE) != 0) { + ::DispatchMessageW(&msg); anyProcessed = true; } } while (waitForEvent && !anyProcessed); @@ -394,7 +396,7 @@ GHOST_TSuccess GHOST_SystemWin32::init() } if (success) { - WNDCLASS wc; + WNDCLASSW wc; wc.style= CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc= s_wndProc; wc.cbClsExtra= 0; @@ -408,10 +410,10 @@ GHOST_TSuccess GHOST_SystemWin32::init() wc.hCursor = ::LoadCursor(0, IDC_ARROW); wc.hbrBackground= (HBRUSH)::GetStockObject(BLACK_BRUSH); wc.lpszMenuName = 0; - wc.lpszClassName= GHOST_WindowWin32::getWindowClassName(); + wc.lpszClassName= L"GHOST_WindowClass"; // Use RegisterClassEx for setting small icon - if (::RegisterClass(&wc) == 0) { + if (::RegisterClassW(&wc) == 0) { success = GHOST_kFailure; } } @@ -719,15 +721,17 @@ GHOST_EventKey* GHOST_SystemWin32::processKeyEvent(GHOST_IWindow *window, RAWINP char utf8_char[6] = {0}; char ascii = 0; - wchar_t utf16[2]={0}; + wchar_t utf16[3]={0}; BYTE state[256] ={0}; - GetKeyboardState(state); + int r; + GetKeyboardState((PBYTE)state); + + if(r = ToUnicodeEx(vk, 0, state, utf16, 2, 0, system->m_keylayout)) - if(ToUnicodeEx(vk, 0, state, utf16, 2, 0, system->m_keylayout)) - WideCharToMultiByte(CP_UTF8, 0, - (wchar_t*)utf16, 1, - (LPSTR) utf8_char, 5, - NULL,NULL); else *utf8_char = 0; + if((r>0 && r<3)){utf16[r]=0; + + conv_utf_16_to_8(utf16,utf8_char,6);} + else if (r==-1) utf8_char[0] = '\0'; @@ -1189,8 +1193,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, * DefWindowProc returns. */ break; - - //////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////// // Other events //////////////////////////////////////////////////////////////////////// case WM_GETTEXT: @@ -1239,17 +1242,17 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, } if (!eventHandled) - lResult = ::DefWindowProc(hwnd, msg, wParam, lParam); + lResult = ::DefWindowProcW(hwnd, msg, wParam, lParam); return lResult; } GHOST_TUns8* GHOST_SystemWin32::getClipboard(bool selection) const { - wchar_t *buffer; char *temp_buff; if ( IsClipboardFormatAvailable(CF_UNICODETEXT) && OpenClipboard(NULL) ) { + wchar_t *buffer; size_t len = 0; HANDLE hData = GetClipboardData( CF_UNICODETEXT ); if (hData == NULL) { @@ -1262,9 +1265,32 @@ GHOST_TUns8* GHOST_SystemWin32::getClipboard(bool selection) const return NULL; } - len = WideCharToMultiByte(CP_UTF8, 0, buffer, -1, NULL, 0, NULL, NULL); - temp_buff = (char*) malloc(len); - WideCharToMultiByte(CP_UTF8, 0, buffer, -1, temp_buff, len, NULL, NULL); + temp_buff = alloc_utf_8_from_16(buffer,0); + + /* Buffer mustn't be accessed after CloseClipboard + it would like accessing free-d memory */ + GlobalUnlock( hData ); + CloseClipboard(); + + return (GHOST_TUns8*)temp_buff; + } else if ( IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(NULL) ) { + char *buffer; + size_t len = 0; + HANDLE hData = GetClipboardData( CF_TEXT ); + if (hData == NULL) { + CloseClipboard(); + return NULL; + } + buffer = (char*)GlobalLock( hData ); + if (!buffer) { + CloseClipboard(); + return NULL; + } + + len = strlen(buffer); + temp_buff = (char*) malloc(len+1); + strncpy(temp_buff, buffer, len); + temp_buff[len] = '\0'; /* Buffer mustn't be accessed after CloseClipboard it would like accessing free-d memory */ @@ -1281,20 +1307,19 @@ void GHOST_SystemWin32::putClipboard(GHOST_TInt8 *buffer, bool selection) const { if(selection) {return;} // for copying the selection, used on X11 - if (OpenClipboard(NULL)) { + if(OpenClipboard(NULL)) { HLOCAL clipbuffer; wchar_t *data; if (buffer) { + size_t len = count_utf_16_from_8(buffer); EmptyClipboard(); - int wlen = MultiByteToWideChar(CP_UTF8, 0, buffer, -1, NULL, 0); - - clipbuffer = LocalAlloc(LMEM_FIXED, wlen * sizeof(wchar_t)); + clipbuffer = LocalAlloc(LMEM_FIXED,sizeof(wchar_t) * len); data = (wchar_t*)GlobalLock(clipbuffer); - - MultiByteToWideChar(CP_UTF8, 0, buffer, -1, data, wlen); - + + conv_utf_8_to_16(buffer, data, len); + LocalUnlock(clipbuffer); SetClipboardData(CF_UNICODETEXT,clipbuffer); } diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index 8e37d1832df..9d105748095 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -41,6 +41,8 @@ #include "GHOST_WindowWin32.h" #include "GHOST_SystemWin32.h" #include "GHOST_DropTargetWin32.h" +#include "utfconv.h" +#include "utf_winfunc.h" // Need glew for some defines #include <GL/glew.h> @@ -64,7 +66,7 @@ #endif #endif -LPCSTR GHOST_WindowWin32::s_windowClassName = "GHOST_WindowClass"; +wchar_t* GHOST_WindowWin32::s_windowClassName = L"GHOST_WindowClass"; const int GHOST_WindowWin32::s_maxTitleLength = 128; HGLRC GHOST_WindowWin32::s_firsthGLRc = NULL; HDC GHOST_WindowWin32::s_firstHDC = NULL; @@ -234,9 +236,10 @@ GHOST_WindowWin32::GHOST_WindowWin32( height = rect.bottom - rect.top; } - m_hWnd = ::CreateWindow( + wchar_t * title_16 = alloc_utf16_from_8((char*)(const char*)title,0); + m_hWnd = ::CreateWindowW( s_windowClassName, // pointer to registered class name - title, // pointer to window name + title_16, // pointer to window name wintype, // window style left, // horizontal position of window top, // vertical position of window @@ -246,11 +249,13 @@ GHOST_WindowWin32::GHOST_WindowWin32( 0, // handle to menu or child-window identifier ::GetModuleHandle(0), // handle to application instance 0); // pointer to window-creation data + free(title_16); } else { - m_hWnd = ::CreateWindow( + wchar_t * title_16 = alloc_utf16_from_8((char*)(const char*)title,0); + m_hWnd = ::CreateWindowW( s_windowClassName, // pointer to registered class name - title, // pointer to window name + title_16, // pointer to window name WS_POPUP | WS_MAXIMIZE, // window style left, // horizontal position of window top, // vertical position of window @@ -260,6 +265,7 @@ GHOST_WindowWin32::GHOST_WindowWin32( 0, // handle to menu or child-window identifier ::GetModuleHandle(0), // handle to application instance 0); // pointer to window-creation data + free(title_16); } if (m_hWnd) { // Register this window as a droptarget. Requires m_hWnd to be valid. @@ -433,13 +439,15 @@ HWND GHOST_WindowWin32::getHWND() const void GHOST_WindowWin32::setTitle(const STR_String& title) { - ::SetWindowText(m_hWnd, title); + wchar_t * title_16 = alloc_utf16_from_8((char*)(const char*)title, 0); + ::SetWindowTextW(m_hWnd, (wchar_t*)title_16); + free(title_16); } void GHOST_WindowWin32::getTitle(STR_String& title) const { - char buf[s_maxTitleLength]; + char buf[s_maxTitleLength];/*CHANGE + never used yet*/ ::GetWindowText(m_hWnd, buf, s_maxTitleLength); STR_String temp (buf); title = buf; diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h index 6eb17affdbf..c8e88c8d844 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.h +++ b/intern/ghost/intern/GHOST_WindowWin32.h @@ -236,7 +236,7 @@ public: * Returns the name of the window class. * @return The name of the window class. */ - static LPCSTR getWindowClassName() { return s_windowClassName; } + static wchar_t* getWindowClassName() { return s_windowClassName; } /** * Register a mouse click event (should be called @@ -351,7 +351,7 @@ protected: /** ITaskbarList3 structure for progress bar*/ ITaskbarList3 * m_Bar; - static LPCSTR s_windowClassName; + static wchar_t* s_windowClassName; static const int s_maxTitleLength; /** WinTab dll handle */ diff --git a/intern/utfconv/CMakeLists.txt b/intern/utfconv/CMakeLists.txt new file mode 100644 index 00000000000..9dd41c28406 --- /dev/null +++ b/intern/utfconv/CMakeLists.txt @@ -0,0 +1,24 @@ +set(INC + . +) + +set(INC_SYS + ${GLEW_INCLUDE_PATH} +) + +set(SRC + utfconv.c + + utfconv.h + #utf_func.h +) + + +if(WIN32) + list(APPEND SRC + utf_winfunc.c + utf_winfunc.h + ) +endif() + +blender_add_lib(bf_intern_utfconv "${SRC}" "${INC}" "${INC_SYS}")
\ No newline at end of file diff --git a/intern/utfconv/SConscript b/intern/utfconv/SConscript new file mode 100644 index 00000000000..1f0fab330d3 --- /dev/null +++ b/intern/utfconv/SConscript @@ -0,0 +1,12 @@ +#!/usr/bin/python +Import ('env') + +sources = env.Glob('*.c') + +incs = '.' +defs = '' + + + +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): + env.BlenderLib ('bf_utfconv', sources, Split(incs), Split(defs), libtype=['intern','player'], priority=[0,0] ) diff --git a/intern/utfconv/utf_winfunc.c b/intern/utfconv/utf_winfunc.c new file mode 100644 index 00000000000..09f5dfff67e --- /dev/null +++ b/intern/utfconv/utf_winfunc.c @@ -0,0 +1,156 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Alexandr Kuznetsov, Andrea Weikert + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifdef WIN32 + +#ifndef _WIN32_IE +#define _WIN32_IE 0x0501 +#endif + +#include "utf_winfunc.h" +#include <io.h> +#include <Windows.h> +#include <wchar.h> + + +FILE * ufopen(const char * filename, const char * mode) +{ + FILE * f = NULL; + UTF16_ENCODE(filename); + UTF16_ENCODE (mode); + + if(filename_16 && mode_16) f = _wfopen(filename_16, mode_16); + + UTF16_UN_ENCODE(mode); + UTF16_UN_ENCODE(filename); + + if(!f) + { + if(f=fopen(filename,mode)) + printf("WARNING: %s is not utf path. Please update it.\n",filename); + } + + return f; +} + +int uopen(const char *filename, int oflag, int pmode) +{ + int f = -1; + UTF16_ENCODE(filename); + + if(filename_16) f = _wopen(filename_16, oflag, pmode); + + UTF16_UN_ENCODE(filename); + + if(f==-1) + { + if((f=open(filename,oflag, pmode))!=-1) + printf("WARNING: %s is not utf path. Please update it.\n",filename); + } + + return f; +} + +int urename(const char *oldname, const char *newname ) +{ + int r = -1; + UTF16_ENCODE(oldname); + UTF16_ENCODE (newname); + + if(oldname_16 && newname_16) r = _wrename(oldname_16, newname_16); + + UTF16_UN_ENCODE(newname); + UTF16_UN_ENCODE(oldname); + return r; +} + +int umkdir(const char *pathname) +{ + + BOOL r = 0; + UTF16_ENCODE(pathname); + + if(pathname_16) r = CreateDirectoryW(pathname_16, NULL); + + UTF16_UN_ENCODE(pathname); + + return r?0:-1; +} + +char * u_alloc_getenv(const char *varname) +{ + char * r = 0; + wchar_t * str; + UTF16_ENCODE(varname); + if(varname_16){ str = _wgetenv(varname_16); + r = alloc_utf_8_from_16(str,0);} + UTF16_UN_ENCODE(varname); + + return r; +} +void u_free_getenv(char *val) +{ + free(val); +} + +int uput_getenv(const char *varname, char * value, size_t buffsize) +{ + int r = 0; + wchar_t * str; + if(!buffsize) return r; + + UTF16_ENCODE(varname); + if(varname_16) + { + str = _wgetenv(varname_16); + conv_utf_16_to_8(str, value, buffsize); + r = 1; + } + UTF16_UN_ENCODE(varname); + + if(!r) value[0] = 0; + + return r; +} + + + +int uputenv(const char *name, const char *value) +{ + int r = -1; + UTF16_ENCODE(name) + UTF16_ENCODE(value) + if(name_16 && value_16) { + if(SetEnvironmentVariableW(name_16,value_16)!=0) + r =0; + else r = -1; + } + UTF16_UN_ENCODE(value) + UTF16_UN_ENCODE(name) + + return r; +} + +#endif
\ No newline at end of file diff --git a/intern/utfconv/utf_winfunc.h b/intern/utfconv/utf_winfunc.h new file mode 100644 index 00000000000..5e88d2de901 --- /dev/null +++ b/intern/utfconv/utf_winfunc.h @@ -0,0 +1,44 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Alexandr Kuznetsov, Andrea Weikert + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifdef WIN32 + + +#include "utfconv.h" +#include <stdio.h> + +FILE * ufopen(const char * filename, const char * mode); +int uopen(const char *filename, int oflag, int pmode); +int urename(const char *oldname, const char *newname ); + +char * u_alloc_getenv(const char *varname); +void u_free_getenv(char *val); + +int uput_getenv(const char *varname, char * value, size_t buffsize); +int uputenv(const char *name, const char *value); + +int umkdir(const char *pathname); + +#endif
\ No newline at end of file diff --git a/intern/utfconv/utfconv.c b/intern/utfconv/utfconv.c new file mode 100644 index 00000000000..9aeca36e55a --- /dev/null +++ b/intern/utfconv/utfconv.c @@ -0,0 +1,232 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Alexandr Kuznetsov, Andrea Weikert + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "utfconv.h" + +size_t count_utf_8_from_16(wchar_t * string16) +{ + int i; + size_t count = 0; + wchar_t u = 0; + if(!string16) return 0; + + for(i=0;u = string16[i];i++) + { + if(u < 0x0080) count+=1; else + if(u < 0x0800) count+=2; else + if(u < 0xD800) count+=3; else + if(u < 0xDC00) { + i++; + if((u = string16[i])==0) break; + if(u >= 0xDC00 && u < 0xE000)count+=4; + } else + if(u < 0xE000) /*illigal*/; else + count+=3; + } + + return ++count; +} + + +size_t count_utf_16_from_8(char * string8) +{ + size_t count = 0; + char u; + char type = 0; + unsigned int u32 = 0; + + if(!string8) return 0; + + for(;(u = *string8);string8++) + { + if(type==0) + { + if((u&0x01<<7) == 0) {count++; u32 = 0; continue;} //1 utf-8 char + if((u&0x07<<5) == 0xC0) {type=1; u32 = u & 0x1F; continue;} //2 utf-8 char + if((u&0x0F<<4) == 0xE0) {type=2; u32 = u & 0x0F; continue;} //3 utf-8 char + if((u&0x1F<<3) == 0xF0) {type=3; u32 = u & 0x07; continue;} //4 utf-8 char + continue; + } else + { + if((u & 0xC0) == 0x80) {u32=(u32<<6) | (u&0x3F); type--;} else + {u32 = 0; type = 0;}; + } + if(type==0) + { + if((0 < u32 && u32 < 0xD800) || (0xE000 <= u32 && u32 < 0x10000)) count++; else + if(0x10000 <= u32 && u32 < 0x110000) count+=2; + u32 = 0; + } + + } + + return ++count; +} + + + + +int conv_utf_16_to_8(wchar_t * in16, char * out8, size_t size8) +{ + char * out8end = out8+size8; + wchar_t u = 0; + int err = 0; + if(!size8 || !in16 || !out8) return UTF_ERROR_NULL_IN; + out8end--; + + for(; out8 < out8end && (u=*in16); in16++, out8++) + { + if(u < 0x0080) *out8 = u; else + if(u < 0x0800) { + if(out8 + 1 >= out8end) break; + *out8++=(0x3<<6) | (0x1F & (u>>6)); + *out8 =(0x1<<7) | (0x3F & (u)); + }else + if(u < 0xD800 || u >= 0xE000) { + if(out8 + 2 >= out8end) break; + *out8++=(0x7<<5) | (0xF & (u>>12)); + *out8++=(0x1<<7) | (0x3F & (u>>6));; + *out8 =(0x1<<7) | (0x3F & (u)); + }else + if(u < 0xDC00) { + wchar_t u2 = *++in16; + + if(!u2) break; + if(u2 >= 0xDC00 && u2 < 0xE000) + { + if(out8 + 3 >= out8end) break; else { + unsigned int uc = 0x10000 + (u2 - 0xDC00) + ((u - 0xD800)<<10); + + *out8++=(0xF<<4) | (0x7 & (uc>>18)); + *out8++=(0x1<<7) | (0x3F & (uc>>12)); + *out8++=(0x1<<7) | (0x3F & (uc>>6)); + *out8 =(0x1<<7) | (0x3F & (uc)); + } + } else {out8--; err|=UTF_ERROR_ILLCHAR;}; + } else + if(u < 0xE000) {out8--; err|=UTF_ERROR_ILLCHAR;} + + + } + + *out8=*out8end=0; + + if(*in16) err|=UTF_ERROR_SMALL; + + return err; +} + + +int conv_utf_8_to_16(char * in8, wchar_t * out16, size_t size16) +{ + char u; + char type = 0; + wchar_t u32 = 0; + wchar_t * out16end = out16+size16; + int err = 0; + if(!size16 || !in8 || !out16) return UTF_ERROR_NULL_IN; + out16end--; + + for(;out16<out16end && (u = *in8);in8++) + { + if(type==0) + { + if((u&0x01<<7) == 0) {*out16=u; out16++; u32 = 0; continue;} //1 utf-8 char + if((u&0x07<<5) == 0xC0) {type=1; u32 = u & 0x1F; continue;} //2 utf-8 char + if((u&0x0F<<4) == 0xE0) {type=2; u32 = u & 0x0F; continue;} //3 utf-8 char + if((u&0x1F<<3) == 0xF0) {type=3; u32 = u & 0x07; continue;} //4 utf-8 char + err|=UTF_ERROR_ILLCHAR; continue; + } else + { + if((u & 0xC0) == 0x80) {u32=(u32<<6) | (u&0x3F); type--;} else + {u32 = 0; type = 0; err|=UTF_ERROR_ILLSEQ;}; + } + if(type==0) + { + if((0 < u32 && u32 < 0xD800) || (0xE000 <= u32 && u32 < 0x10000)) {*out16=u32; out16++;}else + if(0x10000 <= u32 && u32 < 0x110000) { + if(out16 + 1 >= out16end) break; + u32-=0x10000; + *out16 = 0xD800 + (u32 >> 10); + out16++; + *out16 = 0xDC00 + (u32 & 0x3FF); + out16++; + }; + u32 = 0; + } + + } + + *out16=*out16end=0; + + if(*in8) err|=UTF_ERROR_SMALL; + + return err; +} + +int is_ascii(char * in8) +{ + for(in8; *in8; in8++) + if(0x80 & *in8) return 0; + + return 1; +} + +void utf_8_cut_end(char * inout8, size_t maxcutpoint) +{ + const char * start = inout8; + char * cur = inout8 + maxcutpoint; + char cc; + if(!inout8) return; + + cc = *cur; + + + + +} + + + +char * alloc_utf_8_from_16(wchar_t * in16, size_t add) +{ + size_t bsize = count_utf_8_from_16(in16); + char * out8 = NULL; + if(!bsize) return NULL; + out8 = (char*)malloc(sizeof(char) * (bsize + add)); + conv_utf_16_to_8(in16,out8, bsize); + return out8; +} + +wchar_t * alloc_utf16_from_8(char * in8, size_t add) +{ + size_t bsize = count_utf_16_from_8(in8); + wchar_t * out16 = NULL; + if(!bsize) return NULL; + out16 =(wchar_t*) malloc(sizeof(wchar_t) * (bsize + add)); + conv_utf_8_to_16(in8,out16, bsize); + return out16; +} + diff --git a/intern/utfconv/utfconv.h b/intern/utfconv/utfconv.h new file mode 100644 index 00000000000..185c76422e2 --- /dev/null +++ b/intern/utfconv/utfconv.h @@ -0,0 +1,102 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Alexandr Kuznetsov, Andrea Weikert + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <wchar.h> +#include <stdio.h> +#include <stdlib.h> + + + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Counts how many bytes is requered for for future utf-8 string using utf-16 + * @param string-16 pointer to working utf-16 string + * @return How many bytes must be allocated includeng NULL. + */ +size_t count_utf_8_from_16(wchar_t * string16); + +/** + * Counts how many wchar_t (two byte) is requered for for future utf-16 string using utf-8 + * @param string-8 pointer to working utf-8 string + * @return How many bytes must be allocated includeng NULL. + */ +size_t count_utf_16_from_8(char * string8); + +/** + * conv_utf_*** errors + */ +#define UTF_ERROR_NULL_IN 1<<0 /* Error occures when requered parameter is missing*/ +#define UTF_ERROR_ILLCHAR 1<<1 /* Error if character is in illigal UTF rage*/ +#define UTF_ERROR_SMALL 1<<2 /* Passed size is to small. It gives legal string with character missing at the end*/ +#define UTF_ERROR_ILLSEQ 1<<3 /* Error if sequence is broken and doesn't finish*/ + +/** + * Converts utf-16 string to allocated utf-8 string + * @params in16 utf-16 string to convert + * @params out8 utf-8 string to string the conversion + * @params size8 the allocated size in bytes of out8 + * @return Returns any errors occured during conversion. See the block above, + */ +int conv_utf_16_to_8(wchar_t * in16, char * out8, size_t size8); + +/** + * Converts utf-8 string to allocated utf-16 string + * @params in8 utf-8 string to convert + * @params out16 utf-16 string to string the conversion + * @params size16 the allocated size in wchar_t (two byte) of out16 + * @return Returns any errors occured during conversion. See the block above, + */ +int conv_utf_8_to_16(char * in8, wchar_t * out16, size_t size16); + + +/** + * Allocates and converts the utf-8 string from utf-16 + * @params in16 utf-16 string to convert + * @params add any additional size which will be allocated for new utf-8 string in bytes + * @return New allocated and converted utf-8 string or NULL if in16 is 0. + */ +char * alloc_utf_8_from_16(wchar_t * in16, size_t add); + +/** + * Allocates and converts the utf-16 string from utf-8 + * @params in8 utf-8 string to convert + * @params add any additional size which will be allocated for new utf-16 string in wchar_t (two bytes) + * @return New allocated and converted utf-16 string or NULL if in8 is 0. + */ +wchar_t * alloc_utf16_from_8(char * in8, size_t add); + +/* Easy allocation and conversion of new utf-16 string. New string has _16 suffix. Must be deallocated with UTF16_UN_ENCODE in right order*/ +#define UTF16_ENCODE(in8str) if(1){\ + wchar_t * in8str ## _16 = alloc_utf16_from_8((char*)in8str, 0); + +#define UTF16_UN_ENCODE(in8str) \ + free(in8str ## _16 ); }; + +#ifdef __cplusplus +} +#endif
\ No newline at end of file diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 30f4e9f2816..2ef93dd7fa3 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -717,7 +717,7 @@ void BKE_undo_save_quit(void) BLI_make_file_string("/", str, BLI_temporary_dir(), "quit.blend"); - file = open(str,O_BINARY+O_WRONLY+O_CREAT+O_TRUNC, 0666); + file = BLI_open(str,O_BINARY+O_WRONLY+O_CREAT+O_TRUNC, 0666); if(file == -1) { //XXX error("Unable to save %s, check you have permissions", str); return; diff --git a/source/blender/blenkernel/intern/customdata_file.c b/source/blender/blenkernel/intern/customdata_file.c index 4386132fc18..5538267a5f1 100644 --- a/source/blender/blenkernel/intern/customdata_file.c +++ b/source/blender/blenkernel/intern/customdata_file.c @@ -279,7 +279,7 @@ int cdf_read_open(CDataFile *cdf, const char *filename) { FILE *f; - f= fopen(filename, "rb"); + f= BLI_fopen(filename, "rb"); if(!f) return 0; @@ -350,7 +350,7 @@ int cdf_write_open(CDataFile *cdf, const char *filename) CDataFileMeshHeader *mesh; FILE *f; - f= fopen(filename, "wb"); + f= BLI_fopen(filename, "wb"); if(!f) return 0; diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 4300995b68c..053ebf654f0 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -521,7 +521,7 @@ Image *BKE_add_image_file(const char *name) BLI_path_abs(str, G.main->name); /* exists? */ - file= open(str, O_BINARY|O_RDONLY); + file= BLI_open(str, O_BINARY|O_RDONLY, 0); if(file== -1) return NULL; close(file); diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index 0af6b9dd219..1b415f1654f 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -411,7 +411,7 @@ MovieClip *BKE_add_movieclip_file(const char *name) BLI_path_abs(str, G.main->name); /* exists? */ - file= open(str, O_BINARY|O_RDONLY); + file= BLI_open(str, O_BINARY|O_RDONLY,0); if(file== -1) return NULL; close(file); diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c index 4230510dac9..64ccdf9b843 100644 --- a/source/blender/blenkernel/intern/packedFile.c +++ b/source/blender/blenkernel/intern/packedFile.c @@ -186,7 +186,7 @@ PackedFile *newPackedFile(ReportList *reports, const char *filename, const char // open the file // and create a PackedFile structure - file= open(name, O_BINARY|O_RDONLY); + file= BLI_open(name, O_BINARY|O_RDONLY,0); if (file <= 0) { BKE_reportf(reports, RPT_ERROR, "Unable to pack file, source path not found: \"%s\"", name); } else { @@ -292,7 +292,7 @@ int writePackedFile(ReportList *reports, const char *filename, PackedFile *pf, i // make sure the path to the file exists... BLI_make_existing_file(name); - file = open(name, O_BINARY + O_WRONLY + O_CREAT + O_TRUNC, 0666); + file = BLI_open(name, O_BINARY + O_WRONLY + O_CREAT + O_TRUNC, 0666); if (file >= 0) { if (write(file, pf->data, pf->size) != pf->size) { BKE_reportf(reports, RPT_ERROR, "Error writing file: %s", name); @@ -347,7 +347,7 @@ int checkPackedFile(const char *filename, PackedFile *pf) } else { // we'll have to compare the two... - file = open(name, O_BINARY | O_RDONLY); + file = BLI_open(name, O_BINARY | O_RDONLY, 0); if (file < 0) { ret_val = PF_NOFILE; } else { diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index a0668d621e8..978971a04a4 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -4073,7 +4073,7 @@ static void particles_fluid_step(ParticleSimulationData *sim, int UNUSED(cfra)) BLI_path_frame(filename, curFrame, 0); // fixed #frame-no - gzf = gzopen(filename, "rb"); + gzf = BLI_gzopen(filename, "rb"); if (!gzf) { BLI_snprintf(debugStrBuffer, sizeof(debugStrBuffer),"readFsPartData::error - Unable to open file for reading '%s' \n", filename); // XXX bad level call elbeemDebugOut(debugStrBuffer); diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 69e96c7a698..a2425b0a3ac 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -1144,13 +1144,13 @@ static PTCacheFile *ptcache_file_open(PTCacheID *pid, int mode, int cfra) if (!BLI_exists(filename)) { return NULL; } - fp = fopen(filename, "rb"); + fp = BLI_fopen(filename, "rb"); } else if (mode==PTCACHE_FILE_WRITE) { BLI_make_existing_file(filename); /* will create the dir if needs be, same as //textures is created */ - fp = fopen(filename, "wb"); + fp = BLI_fopen(filename, "wb"); } else if (mode==PTCACHE_FILE_UPDATE) { BLI_make_existing_file(filename); - fp = fopen(filename, "rb+"); + fp = BLI_fopen(filename, "rb+"); } if (!fp) diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index ffb8e830ed4..66759edde65 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -44,6 +44,7 @@ #include "BLI_string_utf8.h" #include "BLI_listbase.h" #include "BLI_utildefines.h" +#include "BLI_fileops.h" #include "DNA_constraint_types.h" #include "DNA_controller_types.h" @@ -291,7 +292,7 @@ int reopen_text(Text *text) BLI_strncpy(str, text->name, FILE_MAX); BLI_path_abs(str, G.main->name); - fp= fopen(str, "r"); + fp= BLI_fopen(str, "r"); if(fp==NULL) return 0; /* free memory: */ @@ -387,7 +388,7 @@ Text *add_text(const char *file, const char *relpath) if (relpath) /* can be NULL (bg mode) */ BLI_path_abs(str, relpath); - fp= fopen(str, "r"); + fp= BLI_fopen(str, "r"); if(fp==NULL) return NULL; ta= alloc_libblock(&bmain->text, ID_TXT, BLI_path_basename(str)); diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h index 8fe8456e845..fa1a61998d7 100644 --- a/source/blender/blenlib/BLI_fileops.h +++ b/source/blender/blenlib/BLI_fileops.h @@ -33,6 +33,9 @@ #ifndef __BLI_FILEOPS_H__ #define __BLI_FILEOPS_H__ +#include <stdio.h> + + #ifdef __cplusplus extern "C" { #endif @@ -65,6 +68,10 @@ unsigned int BLI_dir_contents(const char *dir, struct direntry **filelist); /* Files */ +FILE * BLI_fopen(const char * filename, const char * mode); +void* BLI_gzopen(const char * filename, const char * mode); +int BLI_open(const char *filename, int oflag, int pmode); + int BLI_file_is_writable(const char *file); int BLI_file_touch(const char *file); diff --git a/source/blender/blenlib/BLI_winstuff.h b/source/blender/blenlib/BLI_winstuff.h index d939882b105..c393b219785 100644 --- a/source/blender/blenlib/BLI_winstuff.h +++ b/source/blender/blenlib/BLI_winstuff.h @@ -124,7 +124,7 @@ struct dirent { typedef struct _DIR { HANDLE handle; - WIN32_FIND_DATA data; + WIN32_FIND_DATAW data; char path[MAX_PATH]; long dd_loc; long dd_size; diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index ddcc344e939..c06a1240729 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -160,4 +160,10 @@ if(WITH_XDG_USER_DIRS) add_definitions(-DWITH_XDG_USER_DIRS) endif() +if(WIN32) + list(APPEND INC + ../../../intern/utfconv + ) +endif() + blender_add_lib(bf_blenlib "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/blenlib/SConscript b/source/blender/blenlib/SConscript index dda8303eea7..ea51e5b6ab5 100644 --- a/source/blender/blenlib/SConscript +++ b/source/blender/blenlib/SConscript @@ -18,6 +18,7 @@ if env['WITH_BF_BINRELOC']: if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): incs += ' ' + env['BF_PTHREADS_INC'] + incs += ' ../../../intern/utfconv' if env['OURPLATFORM'] == 'linuxcross': if env['WITH_BF_OPENMP']: diff --git a/source/blender/blenlib/intern/dynlib.c b/source/blender/blenlib/intern/dynlib.c index 0bfa5e79eb8..c23feb975df 100644 --- a/source/blender/blenlib/intern/dynlib.c +++ b/source/blender/blenlib/intern/dynlib.c @@ -44,11 +44,17 @@ struct DynamicLibrary { #ifdef WIN32 #include <windows.h> +#include "utf_winfunc.h" +#include "utfconv.h" DynamicLibrary *BLI_dynlib_open(char *name) { DynamicLibrary *lib; - void *handle= LoadLibrary(name); + void *handle; + + UTF16_ENCODE(name); + handle= LoadLibraryW(name_16); + UTF16_UN_ENCODE(name); if(!handle) return NULL; diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c index ab7beeeb8f1..9527ec9466b 100644 --- a/source/blender/blenlib/intern/fileops.c +++ b/source/blender/blenlib/intern/fileops.c @@ -45,6 +45,8 @@ #include <io.h> #include "BLI_winstuff.h" #include "BLI_callbacks.h" +#include "utf_winfunc.h" +#include "utfconv.h" #else #include <unistd.h> // for read close #include <sys/param.h> @@ -77,11 +79,10 @@ int BLI_file_gzip(const char *from, const char *to) /* level 1 is very close to 3 (the default) in terms of file size, * but about twice as fast, best use for speedy saving - campbell */ - gzfile = gzopen(to, "wb1"); + gzfile = BLI_gzopen(to, "wb1"); if(gzfile == NULL) return -1; - - file = open(from, O_BINARY|O_RDONLY); + file = BLI_open(from, O_BINARY|O_RDONLY,0); if(file < 0) return -2; @@ -121,8 +122,7 @@ char *BLI_file_ungzip_to_mem(const char *from_file, int *size_r) size= 0; - gzfile = gzopen( from_file, "rb" ); - + gzfile = BLI_gzopen( from_file, "rb" ); for(;;) { if(mem==NULL) { mem= MEM_callocN(chunk_size, "BLI_ungzip_to_mem"); @@ -158,12 +158,12 @@ int BLI_file_is_writable(const char *filename) int file; /* first try to open without creating */ - file = open(filename, O_BINARY | O_RDWR, 0666); + file = BLI_open(filename, O_BINARY | O_RDWR, 0666); if (file < 0) { /* now try to open and create. a test without actually * creating a file would be nice, but how? */ - file = open(filename, O_BINARY | O_RDWR | O_CREAT, 0666); + file = BLI_open(filename, O_BINARY | O_RDWR | O_CREAT, 0666); if(file < 0) { return 0; @@ -183,13 +183,13 @@ int BLI_file_is_writable(const char *filename) int BLI_file_touch(const char *file) { - FILE *f = fopen(file,"r+b"); + FILE *f = BLI_fopen(file,"r+b"); if (f != NULL) { char c = getc(f); rewind(f); putc(c,f); } else { - f = fopen(file,"wb"); + f = BLI_fopen(file,"wb"); } if (f) { fclose(f); @@ -202,21 +202,63 @@ int BLI_file_touch(const char *file) static char str[MAXPATHLEN+12]; +FILE * BLI_fopen(const char * filename, const char * mode) +{ + return ufopen(filename, mode); +} + +gzFile BLI_gzopen(const char * filename, const char * mode) +{ + gzFile gzfile; + int fi; + + if(!filename || !mode) {return 0;} + else + + { + + wchar_t short_name_16 [256]; + char short_name [256]; + int i=0; + UTF16_ENCODE(filename); + + GetShortPathNameW(filename_16,short_name_16,256); + + for(i=0;i<256;i++) {short_name[i]=short_name_16[i];}; + + + gzfile = gzopen(short_name,mode); + + UTF16_UN_ENCODE(filename); + + } + return gzfile; +} + +int BLI_open(const char *filename, int oflag, int pmode) +{ + return uopen(filename, oflag, pmode); +} + int BLI_delete(const char *file, int dir, int recursive) { int err; + + UTF16_ENCODE(file) if (recursive) { callLocalErrorCallBack("Recursive delete is unsupported on Windows"); err= 1; } else if (dir) { - err= !RemoveDirectory(file); + err= !RemoveDirectoryW(file_16); if (err) printf ("Unable to remove directory"); } else { - err= !DeleteFile(file); + err= !DeleteFileW(file_16); if (err) callLocalErrorCallBack("Unable to delete file"); } + UTF16_UN_ENCODE(file) + return err; } @@ -235,8 +277,13 @@ int BLI_move(const char *file, const char *to) strcat(str, BLI_last_slash(file) + 1); } } + + UTF16_ENCODE(file) + UTF16_ENCODE(str) + err= !MoveFileW(file_16, str_16); + UTF16_UN_ENCODE(str) + UTF16_UN_ENCODE(file) - err= !MoveFile(file, str); if (err) { callLocalErrorCallBack("Unable to move file"); printf(" Move from '%s' to '%s' failed\n", file, str); @@ -262,8 +309,12 @@ int BLI_copy(const char *file, const char *to) } } - err= !CopyFile(file,str,FALSE); - + UTF16_ENCODE(file) + UTF16_ENCODE(str) + err= !CopyFileW(file_16,str_16,FALSE); + UTF16_UN_ENCODE(str) + UTF16_UN_ENCODE(file) + if (err) { callLocalErrorCallBack("Unable to copy file!"); printf(" Copy from '%s' to '%s' failed\n", file, str); @@ -292,7 +343,7 @@ void BLI_dir_create_recursive(const char *dirname) BLI_strncpy(tmp, dirname, sizeof(tmp)); lslash= BLI_last_slash(tmp); - + if (lslash == tmp + strlen(tmp) - 1) { *lslash = 0; } @@ -307,8 +358,8 @@ void BLI_dir_create_recursive(const char *dirname) } if(dirname[0]) /* patch, this recursive loop tries to create a nameless directory */ - if (!CreateDirectory(dirname, NULL)) - callLocalErrorCallBack("Unable to create directory\n"); + if (umkdir(dirname)==-1) + printf("Unable to create directory %s\n",dirname); } int BLI_rename(const char *from, const char *to) @@ -318,8 +369,8 @@ int BLI_rename(const char *from, const char *to) /* make sure the filenames are different (case insensitive) before removing */ if (BLI_exists(to) && BLI_strcasecmp(from, to)) if(BLI_delete(to, 0, 0)) return 1; - - return rename(from, to); + + return urename(from, to); } #else /* The UNIX world */ @@ -499,6 +550,21 @@ static int delete_single_file(const char *from, const char *UNUSED(to)) return recursiveOp_Callback_OK; } +FILE * BLI_fopen(const char * filename, const char * mode) +{ + return fopen(filename, mode); +} + +gzFile BLI_gzopen(const char * filename, const char * mode) +{ + return gzopen(filename, mode); +} + +int BLI_open(const char *filename, int oflag, int pmode) +{ + return open(filename, oflag, pmode); +} + int BLI_delete(const char *file, int dir, int recursive) { if(strchr(file, '"')) { diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index 9c80fa9ca15..ccf85934788 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -62,6 +62,7 @@ #endif #ifdef WIN32 +#include "utf_winfunc.h" # include <io.h> # ifdef _WIN32_IE # undef _WIN32_IE @@ -825,10 +826,8 @@ const char *BLI_getDefaultDocumentFolder(void) HRESULT hResult; /* Check for %HOME% env var */ - - ret = getenv("HOME"); - if(ret) { - if (BLI_is_dir(ret)) return ret; + if(uput_getenv("HOME",documentfolder,MAXPATHLEN)) { + if (BLI_is_dir(documentfolder)) return documentfolder; } /* add user profile support for WIN 2K / NT. @@ -1186,7 +1185,9 @@ void BLI_setenv(const char *env, const char*val) /* non-free windows */ #elif (defined(WIN32) || defined(WIN64)) /* not free windows */ - _putenv_s(env, val); + uputenv(env, val); + + #else /* linux/osx/bsd */ setenv(env, val, 1); @@ -1774,17 +1775,23 @@ static void bli_where_am_i(char *fullname, const size_t maxlen, const char *name #endif #ifdef _WIN32 - if(GetModuleFileName(0, fullname, maxlen)) { + wchar_t * fullname_16 = MEM_mallocN(maxlen*sizeof(wchar_t), "ProgramPath"); + if(GetModuleFileNameW(0, fullname_16, maxlen)) { + conv_utf_16_to_8(fullname_16,fullname, maxlen); if(!BLI_exists(fullname)) { printf("path can't be found: \"%.*s\"\n", maxlen, fullname); MessageBox(NULL, "path contains invalid characters or is too long (see console)", "Error", MB_OK); } + MEM_freeN(fullname_16); return; } + + MEM_freeN(fullname_16); #endif /* unix and non linux */ if (name && name[0]) { + BLI_strncpy(fullname, name, maxlen); if (name[0] == '.') { char wdir[FILE_MAX]= ""; diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c index 29f11ee0550..363052c7255 100644 --- a/source/blender/blenlib/intern/storage.c +++ b/source/blender/blenlib/intern/storage.c @@ -78,6 +78,7 @@ #include <io.h> #include <direct.h> #include "BLI_winstuff.h" +#include "utfconv.h" #endif @@ -86,10 +87,13 @@ #include "DNA_listBase.h" -#include "BLI_fileops.h" #include "BLI_listbase.h" #include "BLI_linklist.h" +#include "BLI_fileops.h" + +#include "BLI_fileops_types.h" #include "BLI_string.h" +#include "BLI_fileops.h" #include "BKE_utildefines.h" @@ -210,13 +214,22 @@ static void bli_builddir(const char *dirname, const char *relname) buf[rellen]='/'; rellen++; } - +#ifndef WIN32 if (chdir(dirname) == -1) { perror(dirname); return; } +#else + UTF16_ENCODE(dirname) + if(!SetCurrentDirectoryW(dirname_16)){ + perror(dirname); + free(dirname_16); + return; + } + UTF16_UN_ENCODE(dirname) - if ( (dir = (DIR *)opendir(".")) ) { +#endif + if ( (dir = (DIR *)opendir(".")) ){ while ((fname = (struct dirent*) readdir(dir)) != NULL) { dlink = (struct dirlink *)malloc(sizeof(struct dirlink)); if (dlink) { @@ -250,11 +263,16 @@ static void bli_builddir(const char *dirname, const char *relname) files[actnum].relname = dlink->name; 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. +// Excluding other than current MSVC compiler until able to test +#ifdef WIN32 + {wchar_t * name_16 = alloc_utf16_from_8(dlink->name,0); #if (defined(WIN32) || defined(WIN64)) && (_MSC_VER>=1500) - _stat64(dlink->name,&files[actnum].s); + _wstat64(name_16,&files[actnum].s); #elif defined(__MINGW32__) _stati64(dlink->name,&files[actnum].s); +#endif + free(name_16);}; + #else stat(dlink->name,&files[actnum].s); #endif @@ -423,13 +441,13 @@ size_t BLI_file_descriptor_size(int file) struct stat buf; if (file <= 0) return (-1); - fstat(file, &buf); + fstat(file, &buf);//CHANGE return (buf.st_size); } size_t BLI_file_size(const char *path) { - int size, file = open(path, O_BINARY|O_RDONLY); + int size, file = BLI_open(path, O_BINARY|O_RDONLY, 0); if (file == -1) return -1; @@ -442,27 +460,26 @@ size_t BLI_file_size(const char *path) int BLI_exists(const char *name) { -#if defined(WIN32) && !defined(__MINGW32__) +#if defined(WIN32) +#ifndef __MINGW32__ struct _stat64i32 st; - /* 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_MAX]; - int len, res; - BLI_strncpy(tmp, name, FILE_MAX); - len = strlen(tmp); - if (len > 3 && ( tmp[len-1]=='\\' || tmp[len-1]=='/') ) tmp[len-1] = '\0'; - res = _stat(tmp, &st); - if (res == -1) return(0); -#elif defined(__MINGW32__) +#else struct _stati64 st; - char tmp[FILE_MAX]; +#endif + /* 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 */ + wchar_t * tmp_16 = alloc_utf16_from_8(name, 0); int len, res; - BLI_strncpy(tmp, name, FILE_MAX); - len = strlen(tmp); - if (len > 3 && ( tmp[len-1]=='\\' || tmp[len-1]=='/') ) tmp[len-1] = '\0'; - res = _stati64(tmp, &st); - if (res) return(0); + len = wcslen(tmp_16); + if (len > 3 && ( tmp_16[len-1]==L'\\' || tmp_16[len-1]==L'/') ) tmp_16[len-1] = '\0'; +#ifndef __MINGW32__ + res = _wstat(tmp_16, &st); +#else + res = _wstati64(tmp_16, &st); +#endif + free(tmp_16); + if (res == -1) return(0); #else struct stat st; if (stat(name,&st)) return(0); @@ -484,7 +501,7 @@ int BLI_is_file(const char *path) LinkNode *BLI_file_read_as_lines(const char *name) { - FILE *fp= fopen(name, "r"); + FILE *fp= BLI_fopen(name, "r"); LinkNode *lines= NULL; char *buf; size_t size; @@ -530,11 +547,23 @@ void BLI_file_free_lines(LinkNode *lines) int BLI_file_older(const char *file1, const char *file2) { +#if WIN32 + struct _stat st1, st2; + + UTF16_ENCODE(file1) + UTF16_ENCODE(file2) + + if(_wstat(file1_16, &st1)) return 0; + if(_wstat(file2_16, &st2)) return 0; + + UTF16_UN_ENCODE(file2) + UTF16_UN_ENCODE(file1) +#else struct stat st1, st2; if(stat(file1, &st1)) return 0; if(stat(file2, &st2)) return 0; - +#endif return (st1.st_mtime < st2.st_mtime); } diff --git a/source/blender/blenlib/intern/winstuff.c b/source/blender/blenlib/intern/winstuff.c index 4665b08b202..7fc2e52255c 100644 --- a/source/blender/blenlib/intern/winstuff.c +++ b/source/blender/blenlib/intern/winstuff.c @@ -47,13 +47,16 @@ #define WIN32_SKIP_HKEY_PROTECTION // need to use HKEY #include "BLI_winstuff.h" - /* FILE_MAX */ +#include "utf_winfunc.h" +#include "utfconv.h" + + /* FILE_MAXDIR + FILE_MAXFILE */ int BLI_getInstallationDir( char * str ) { char dir[FILE_MAXDIR]; int a; - + /*change to utf support*/ GetModuleFileName(NULL,str,FILE_MAX); BLI_split_dir_part(str, dir, sizeof(dir)); /* shouldn't be relative */ a = strlen(dir); @@ -169,7 +172,9 @@ void RegisterBlendExtension(void) DIR *opendir (const char *path) { - if (GetFileAttributes(path) & FILE_ATTRIBUTE_DIRECTORY) { + wchar_t * path_16 = alloc_utf16_from_8(path, 0); + + if (GetFileAttributesW(path_16) & FILE_ATTRIBUTE_DIRECTORY) { DIR *newd= MEM_mallocN(sizeof(DIR), "opendir"); newd->handle = INVALID_HANDLE_VALUE; @@ -180,29 +185,56 @@ DIR *opendir (const char *path) newd->direntry.d_reclen= 0; newd->direntry.d_name= NULL; + free(path_16); return newd; } else { + free(path_16); return NULL; } } -struct dirent *readdir(DIR *dp) +static char * BLI_alloc_utf_8_from_16(wchar_t * in16, size_t add) +{ + size_t bsize = count_utf_8_from_16(in16); + char * out8 = NULL; + if(!bsize) return NULL; + out8 = (char*)MEM_mallocN(sizeof(char) * (bsize + add),"UTF-8 String"); + conv_utf_16_to_8(in16,out8, bsize); + return out8; +} + +static wchar_t * BLI_alloc_utf16_from_8(char * in8, size_t add) { + size_t bsize = count_utf_16_from_8(in8); + wchar_t * out16 = NULL; + if(!bsize) return NULL; + out16 =(wchar_t*) MEM_mallocN(sizeof(wchar_t) * (bsize + add), "UTF-16 String"); + conv_utf_8_to_16(in8,out16, bsize); + return out16; +} + + + +struct dirent *readdir(DIR *dp) { + char * FileName; + size_t size; if (dp->direntry.d_name) { MEM_freeN(dp->direntry.d_name); dp->direntry.d_name= NULL; } if (dp->handle==INVALID_HANDLE_VALUE) { - dp->handle= FindFirstFile(dp->path, &(dp->data)); + wchar_t * path_16 = alloc_utf16_from_8(dp->path, 0); + dp->handle= FindFirstFileW(path_16, &(dp->data)); + free(path_16); if (dp->handle==INVALID_HANDLE_VALUE) return NULL; - dp->direntry.d_name= BLI_strdup(dp->data.cFileName); - + dp->direntry.d_name= BLI_alloc_utf_8_from_16(dp->data.cFileName, 0); + 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_alloc_utf_8_from_16(dp->data.cFileName,0); return &dp->direntry; } else { diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 95a76dac616..7a6e23cd5bb 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -990,7 +990,7 @@ FileData *blo_openblenderfile(const char *filepath, ReportList *reports) { gzFile gzfile; errno= 0; - gzfile= gzopen(filepath, "rb"); + gzfile= BLI_gzopen(filepath, "rb"); if (gzfile == (gzFile)Z_NULL) { BKE_reportf(reports, RPT_ERROR, "Unable to open \"%s\": %s.", filepath, errno ? strerror(errno) : "Unknown error reading file"); diff --git a/source/blender/blenloader/intern/runtime.c b/source/blender/blenloader/intern/runtime.c index 3f8a9807f18..88f602641ff 100644 --- a/source/blender/blenloader/intern/runtime.c +++ b/source/blender/blenloader/intern/runtime.c @@ -68,7 +68,7 @@ static int handle_read_msb_int(int handle) int BLO_is_a_runtime(const char *path) { - int res= 0, fd= open(path, O_BINARY|O_RDONLY, 0); + int res= 0, fd= BLI_open(path, O_BINARY|O_RDONLY, 0); int datastart; char buf[8]; @@ -102,7 +102,7 @@ BlendFileData *BLO_read_runtime(const char *path, ReportList *reports) int fd, datastart; char buf[8]; - fd= open(path, O_BINARY|O_RDONLY, 0); + fd= BLI_open(path, O_BINARY|O_RDONLY, 0); if(fd==-1) { BKE_reportf(reports, RPT_ERROR, "Unable to open \"%s\": %s.", path, strerror(errno)); diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 8cd6712c560..02de7a371ff 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -2887,7 +2887,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL /* open temporary file, so we preserve the original in case we crash */ BLI_snprintf(tempname, sizeof(tempname), "%s@", filepath); - file = open(tempname,O_BINARY+O_WRONLY+O_CREAT+O_TRUNC, 0666); + file = BLI_open(tempname,O_BINARY+O_WRONLY+O_CREAT+O_TRUNC, 0666); if(file == -1) { BKE_reportf(reports, RPT_ERROR, "Can't open file %s for writing: %s.", tempname, strerror(errno)); return 0; diff --git a/source/blender/editors/armature/reeb.c b/source/blender/editors/armature/reeb.c index bb24a1d8412..e832247e67c 100644 --- a/source/blender/editors/armature/reeb.c +++ b/source/blender/editors/armature/reeb.c @@ -2051,7 +2051,7 @@ void REEB_exportGraph(ReebGraph *rg, int count) else { sprintf(filename, "test%05i.txt", count); } - f = fopen(filename, "w"); + f = BLI_fopen(filename, "w"); for(arc = rg->arcs.first; arc; arc = arc->next) { diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index efde93b4ad7..4170b7e3299 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -348,7 +348,7 @@ static int paste_file(bContext *C, ReportList *reports, const char *filename) int filelen; char *strp; - fp= fopen(filename, "r"); + fp= BLI_fopen(filename, "r"); if(!fp) { if(reports) diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c index dbdee3baca8..43b1a4517ad 100644 --- a/source/blender/editors/physics/physics_fluid.c +++ b/source/blender/editors/physics/physics_fluid.c @@ -684,7 +684,7 @@ static int fluid_init_filepaths(Object *fsDomain, char *targetDir, char *targetF // check selected directory // simply try to open cfg file for writing to test validity of settings - fileCfg = fopen(targetFile, "w"); + fileCfg = BLI_fopen(targetFile, "w"); if(fileCfg) { dirExist = 1; fclose(fileCfg); // remove cfg dummy from directory test diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c index 4c9d2be791b..8b98b942f42 100644 --- a/source/blender/editors/space_file/fsmenu.c +++ b/source/blender/editors/space_file/fsmenu.c @@ -233,7 +233,7 @@ void fsmenu_write_file(struct FSMenu* fsmenu, const char *filename) FSMenuEntry *fsme= NULL; int nskip= 0; - FILE *fp = fopen(filename, "w"); + FILE *fp = BLI_fopen(filename, "w"); if (!fp) return; fprintf(fp, "[Bookmarks]\n"); @@ -262,7 +262,7 @@ void fsmenu_read_bookmarks(struct FSMenu* fsmenu, const char *filename) FSMenuCategory category = FS_CATEGORY_BOOKMARKS; FILE *fp; - fp = fopen(filename, "r"); + fp = BLI_fopen(filename, "r"); if (!fp) return; while ( fgets ( line, 256, fp ) != NULL ) /* read a line */ diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 2f6e5082fdc..4c6357f7505 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -460,7 +460,7 @@ static void txt_write_file(Text *text, ReportList *reports) BLI_strncpy(filepath, text->name, FILE_MAX); BLI_path_abs(filepath, G.main->name); - fp= fopen(filepath, "w"); + fp= BLI_fopen(filepath, "w"); if(fp==NULL) { BKE_reportf(reports, RPT_ERROR, "Unable to save \"%s\": %s", filepath, errno ? strerror(errno) : "Unknown error writing file"); return; diff --git a/source/blender/imbuf/CMakeLists.txt b/source/blender/imbuf/CMakeLists.txt index 649b7cb1c11..aa4454562b4 100644 --- a/source/blender/imbuf/CMakeLists.txt +++ b/source/blender/imbuf/CMakeLists.txt @@ -180,4 +180,10 @@ if(WITH_IMAGE_HDR) add_definitions(-DWITH_HDR) endif() +if(WIN32) + list(APPEND INC + ../../../intern/utfconv + ) +endif() + blender_add_lib(bf_imbuf "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/imbuf/SConscript b/source/blender/imbuf/SConscript index ca56003845f..b2b526ca17d 100644 --- a/source/blender/imbuf/SConscript +++ b/source/blender/imbuf/SConscript @@ -17,6 +17,7 @@ defs = [] if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): incs += ' ' + env['BF_PTHREADS_INC'] + incs += ' ../../../intern/utfconv' if env['WITH_BF_OPENEXR']: defs.append('WITH_OPENEXR') diff --git a/source/blender/imbuf/intern/bmp.c b/source/blender/imbuf/intern/bmp.c index 1b6184c8b58..1e13f5d913b 100644 --- a/source/blender/imbuf/intern/bmp.c +++ b/source/blender/imbuf/intern/bmp.c @@ -216,7 +216,7 @@ int imb_savebmp(struct ImBuf *ibuf, const char *name, int flags) bytesize = (ibuf->x * 3 + extrabytes) * ibuf->y; data = (uchar *) ibuf->rect; - ofile = fopen(name,"wb"); + ofile = BLI_fopen(name,"wb"); if (!ofile) return 0; putShortLSB(19778,ofile); /* "BM" */ diff --git a/source/blender/imbuf/intern/cineon/cineonlib.c b/source/blender/imbuf/intern/cineon/cineonlib.c index 810ed7b26a4..a10d8c67051 100644 --- a/source/blender/imbuf/intern/cineon/cineonlib.c +++ b/source/blender/imbuf/intern/cineon/cineonlib.c @@ -38,6 +38,7 @@ #include <string.h> /* memset */ #include "BLI_utildefines.h" +#include "BLI_fileops.h" #include "cin_debug_stuff.h" #include "logmemfile.h" @@ -523,7 +524,7 @@ cineonOpen(const char* filename) { cineon->memcursor = 0; cineon->membuffersize = 0; - cineon->file = fopen(filename, "rb"); + cineon->file = BLI_fopen(filename, "rb"); if (cineon->file == 0) { if (verbose) d_printf("Failed to open file \"%s\".\n", filename); cineonClose(cineon); @@ -727,7 +728,7 @@ cineonCreate(const char* filename, int width, int height, int depth) { cineon->lineBuffer = 0; cineon->pixelBuffer = 0; - cineon->file = fopen(filename, "wb"); + cineon->file = BLI_fopen(filename, "wb"); if (cineon->file == 0) { if (verbose) d_printf("Couldn't open file %s\n", filename); cineonClose(cineon); diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c index a63a2ea1dab..01177b01178 100644 --- a/source/blender/imbuf/intern/cineon/dpxlib.c +++ b/source/blender/imbuf/intern/cineon/dpxlib.c @@ -38,6 +38,7 @@ #include <string.h> /* memset */ #include "cin_debug_stuff.h" #include "logmemfile.h" +#include "BLI_fileops.h" static void fillDpxChannelInfo(DpxFile* dpx, DpxChannelInformation* chan, int des) { @@ -401,7 +402,7 @@ intern_dpxOpen(int mode, const char* bytestuff, int bufsize) { if (mode == LFREALFILE) { filename = bytestuff; - dpx->file = fopen(filename, "rb"); + dpx->file = BLI_fopen(filename, "rb"); if (dpx->file == 0) { if (verbose) d_printf("Failed to open file \"%s\".\n", filename); dpxClose(dpx); @@ -589,7 +590,7 @@ dpxCreate(const char* filename, int width, int height, int depth) { dpx->lineBuffer = 0; dpx->pixelBuffer = 0; - dpx->file = fopen(filename, "wb"); + dpx->file = BLI_fopen(filename, "wb"); if (dpx->file == 0) { if (verbose) d_printf("Couldn't open file %s\n", filename); dpxClose(dpx); @@ -687,7 +688,7 @@ dpxDump(const char* filename) { DpxMainHeader header; FILE* file; - file = fopen(filename, "rb"); + file = BLI_fopen(filename, "rb"); if (file == 0) { d_printf("Failed to open file \"%s\".\n", filename); return; diff --git a/source/blender/imbuf/intern/cineon/logImageLib.c b/source/blender/imbuf/intern/cineon/logImageLib.c index 123d0b42979..dc50d93bf18 100644 --- a/source/blender/imbuf/intern/cineon/logImageLib.c +++ b/source/blender/imbuf/intern/cineon/logImageLib.c @@ -36,6 +36,7 @@ #include <netinet/in.h> /* htonl() */ #endif #include <string.h> /* memset */ +#include "BLI_fileops.h" #define MIN_GAMMA 0.01 #define MAX_GAMMA 99.9 @@ -154,7 +155,7 @@ logImageDump(const char* filename) U32 magic; - FILE* foo = fopen(filename, "rb"); + FILE* foo = BLI_fopen(filename, "rb"); if (foo == 0) { return; } diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c index cf354371ddc..dcbce6d028c 100644 --- a/source/blender/imbuf/intern/indexer.c +++ b/source/blender/imbuf/intern/indexer.c @@ -81,7 +81,7 @@ anim_index_builder * IMB_index_builder_create(const char * name) BLI_make_existing_file(rv->temp_name); - rv->fp = fopen(rv->temp_name, "wb"); + rv->fp = BLI_fopen(rv->temp_name, "wb"); if (!rv->fp) { fprintf(stderr, "Couldn't open index target: %s! " @@ -140,7 +140,7 @@ void IMB_index_builder_finish(anim_index_builder * fp, int rollback) unlink(fp->temp_name); } else { unlink(fp->name); - rename(fp->temp_name, fp->name); + BLI_rename(fp->temp_name, fp->name); } MEM_freeN(fp); @@ -150,7 +150,7 @@ struct anim_index * IMB_indexer_open(const char * name) { char header[13]; struct anim_index * idx; - FILE * fp = fopen(name, "rb"); + FILE * fp = BLI_fopen(name, "rb"); int i; if (!fp) { @@ -690,7 +690,7 @@ static void free_proxy_output_ffmpeg(struct proxy_output_ctx * ctx, get_proxy_filename(ctx->anim, ctx->proxy_size, fname, FALSE); unlink(fname); - rename(fname_tmp, fname); + BLI_rename(fname_tmp, fname); } MEM_freeN(ctx); diff --git a/source/blender/imbuf/intern/iris.c b/source/blender/imbuf/intern/iris.c index 83351b5e0e4..38fc6f92c83 100644 --- a/source/blender/imbuf/intern/iris.c +++ b/source/blender/imbuf/intern/iris.c @@ -674,7 +674,7 @@ static int output_iris(unsigned int *lptr, int xsize, int ysize, int zsize, cons int rlebuflen, goodwrite; goodwrite = 1; - outf = fopen(name, "wb"); + outf = BLI_fopen(name, "wb"); if(!outf) return 0; tablen = ysize*zsize*sizeof(int); diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c index c2bdb44be10..87450170c66 100644 --- a/source/blender/imbuf/intern/jp2.c +++ b/source/blender/imbuf/intern/jp2.c @@ -731,7 +731,7 @@ int imb_savejp2(struct ImBuf *ibuf, const char *name, int flags) codestream_length = cio_tell(cio); /* write the buffer to disk */ - f = fopen(name, "wb"); + f = BLI_fopen(name, "wb"); if (!f) { fprintf(stderr, "failed to open %s for writing\n", name); diff --git a/source/blender/imbuf/intern/jpeg.c b/source/blender/imbuf/intern/jpeg.c index 2aab497649a..75a5f274413 100644 --- a/source/blender/imbuf/intern/jpeg.c +++ b/source/blender/imbuf/intern/jpeg.c @@ -608,7 +608,7 @@ static int save_stdjpeg(const char *name, struct ImBuf *ibuf) struct jpeg_compress_struct _cinfo, *cinfo = &_cinfo; struct my_error_mgr jerr; - if ((outfile = fopen(name, "wb")) == NULL) return 0; + if ((outfile = BLI_fopen(name, "wb")) == NULL) return 0; jpeg_default_quality = 75; cinfo->err = jpeg_std_error(&jerr.pub); @@ -642,7 +642,7 @@ static int save_vidjpeg(const char *name, struct ImBuf *ibuf) struct jpeg_compress_struct _cinfo, *cinfo = &_cinfo; struct my_error_mgr jerr; - if ((outfile = fopen(name, "wb")) == NULL) return 0; + if ((outfile = BLI_fopen(name, "wb")) == NULL) return 0; jpeg_default_quality = 90; cinfo->err = jpeg_std_error(&jerr.pub); @@ -712,7 +712,7 @@ static int save_maxjpeg(const char *name, struct ImBuf *ibuf) struct jpeg_compress_struct _cinfo, *cinfo = &_cinfo; struct my_error_mgr jerr; - if ((outfile = fopen(name, "wb")) == NULL) return 0; + if ((outfile = BLI_fopen(name, "wb")) == NULL) return 0; jpeg_default_quality = 100; cinfo->err = jpeg_std_error(&jerr.pub); diff --git a/source/blender/imbuf/intern/png.c b/source/blender/imbuf/intern/png.c index 84f3e18591d..78c7c672e22 100644 --- a/source/blender/imbuf/intern/png.c +++ b/source/blender/imbuf/intern/png.c @@ -195,7 +195,7 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags) Flush); } else { - fp = fopen(name, "wb"); + fp = BLI_fopen(name, "wb"); if (!fp) { png_destroy_write_struct(&png_ptr, &info_ptr); MEM_freeN(pixels); diff --git a/source/blender/imbuf/intern/radiance_hdr.c b/source/blender/imbuf/intern/radiance_hdr.c index 9265da8d8dc..42e4db54f3f 100644 --- a/source/blender/imbuf/intern/radiance_hdr.c +++ b/source/blender/imbuf/intern/radiance_hdr.c @@ -332,7 +332,7 @@ static void writeHeader(FILE *file, int width, int height) int imb_savehdr(struct ImBuf *ibuf, const char *name, int flags) { - FILE* file = fopen(name, "wb"); + FILE* file = BLI_fopen(name, "wb"); float *fp= NULL; int y, width=ibuf->x, height=ibuf->y; unsigned char *cp= NULL; diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c index c2f73efa63f..2ee389a42f6 100644 --- a/source/blender/imbuf/intern/readimage.c +++ b/source/blender/imbuf/intern/readimage.c @@ -126,7 +126,7 @@ ImBuf *IMB_loadiffname(const char *filepath, int flags) imb_cache_filename(filepath_tx, filepath, flags); - file = open(filepath_tx, O_BINARY|O_RDONLY); + file = BLI_open(filepath_tx, O_BINARY|O_RDONLY, 0); if(file < 0) return NULL; ibuf= IMB_loadifffile(file, flags, filepath_tx); @@ -152,7 +152,7 @@ ImBuf *IMB_testiffname(const char *filepath, int flags) imb_cache_filename(filepath_tx, filepath, flags); - file = open(filepath_tx,O_BINARY|O_RDONLY); + file = BLI_open(filepath_tx,O_BINARY|O_RDONLY,0); if(file < 0) return NULL; ibuf=IMB_loadifffile(file, flags|IB_test|IB_multilayer, filepath_tx); @@ -195,7 +195,7 @@ void imb_loadtile(ImBuf *ibuf, int tx, int ty, unsigned int *rect) { int file; - file = open(ibuf->cachename, O_BINARY|O_RDONLY); + file = BLI_open(ibuf->cachename, O_BINARY|O_RDONLY, 0); if(file < 0) return; imb_loadtilefile(ibuf, file, tx, ty, rect); diff --git a/source/blender/imbuf/intern/targa.c b/source/blender/imbuf/intern/targa.c index b5552a174a9..1801c1a8ef9 100644 --- a/source/blender/imbuf/intern/targa.c +++ b/source/blender/imbuf/intern/targa.c @@ -268,7 +268,7 @@ int imb_savetarga(struct ImBuf * ibuf, const char *name, int flags) if (ibuf->planes==32) { buf[17] |= 0x08; } - fildes = fopen(name,"wb"); + fildes = BLI_fopen(name,"wb"); if (!fildes) return 0; if (fwrite(buf, 1, 18,fildes) != 18) { diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c index fdc9e50bcd8..be716870dad 100644 --- a/source/blender/imbuf/intern/thumbs.c +++ b/source/blender/imbuf/intern/thumbs.c @@ -61,6 +61,7 @@ #include <process.h> /* getpid */ #include <direct.h> /* chdir */ #include "BLI_winstuff.h" +#include "utfconv.h" #else #include <unistd.h> #endif @@ -70,8 +71,12 @@ static int get_thumb_dir( char* dir , ThumbSize size) { #ifdef WIN32 + wchar_t dir_16 [MAX_PATH]; /* yes, applications shouldn't store data there, but so does GIMP :)*/ - SHGetSpecialFolderPath(0, dir, CSIDL_PROFILE, 0); + SHGetSpecialFolderPathW(0, dir_16, CSIDL_PROFILE, 0); + conv_utf_16_to_8(dir_16,dir,FILE_MAX); + + #else const char* home = getenv("HOME"); if (!home) return 0; diff --git a/source/blender/imbuf/intern/thumbs_blend.c b/source/blender/imbuf/intern/thumbs_blend.c index 1068eccc6e0..fd0be89df0d 100644 --- a/source/blender/imbuf/intern/thumbs_blend.c +++ b/source/blender/imbuf/intern/thumbs_blend.c @@ -30,6 +30,7 @@ #include "zlib.h" #include "BLI_utildefines.h" +#include "BLI_fileops.h" #include "BKE_utildefines.h" #include "BKE_global.h" @@ -123,9 +124,8 @@ static ImBuf *loadblend_thumb(gzFile gzfile) ImBuf *IMB_loadblend_thumb(const char *path) { gzFile gzfile; - /* not necessarily a gzip */ - gzfile = gzopen(path, "rb"); + gzfile = BLI_gzopen(path, "rb"); if (NULL == gzfile ) { return NULL; diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c index b7eba1002c5..fdcc0641628 100644 --- a/source/blender/imbuf/intern/util.c +++ b/source/blender/imbuf/intern/util.c @@ -159,7 +159,7 @@ static int IMB_ispic_name(const char *name) if(((st.st_mode) & S_IFMT) != S_IFREG) return FALSE; - if((fp = open(name,O_BINARY|O_RDONLY)) < 0) + if((fp = BLI_open(name,O_BINARY|O_RDONLY, 0)) < 0) return FALSE; if(read(fp, buf, 32) != 32) { diff --git a/source/blender/modifiers/intern/MOD_fluidsim_util.c b/source/blender/modifiers/intern/MOD_fluidsim_util.c index 31a50a6a16b..2ccae9671b3 100644 --- a/source/blender/modifiers/intern/MOD_fluidsim_util.c +++ b/source/blender/modifiers/intern/MOD_fluidsim_util.c @@ -184,7 +184,7 @@ static DerivedMesh *fluidsim_read_obj(const char *filename, const MPoly *mp_exam // ------------------------------------------------ // get numverts + numfaces first // ------------------------------------------------ - gzf = gzopen(filename, "rb"); + gzf = BLI_gzopen(filename, "rb"); if (!gzf) { return NULL; @@ -216,7 +216,7 @@ static DerivedMesh *fluidsim_read_obj(const char *filename, const MPoly *mp_exam if(!numfaces || !numverts || !gotBytes) return NULL; - gzf = gzopen(filename, "rb"); + gzf = BLI_gzopen(filename, "rb"); if (!gzf) { return NULL; @@ -409,7 +409,7 @@ static void fluidsim_read_vel_cache(FluidsimModifierData *fluidmd, DerivedMesh * filename[len-5] = 'e'; filename[len-4] = 'l'; - gzf = gzopen(filename, "rb"); + gzf = BLI_gzopen(filename, "rb"); if (!gzf) { MEM_freeN(fss->meshVelocities); diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 52272bdb697..f3d21c74080 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -52,6 +52,7 @@ #include "DNA_text_types.h" #include "BLI_path_util.h" +#include "BLI_fileops.h" #include "BLI_math_base.h" #include "BLI_string.h" #include "BLI_string_utf8.h" @@ -388,7 +389,7 @@ static int python_script_exec(bContext *C, const char *fn, struct Text *text, } else { - FILE *fp = fopen(fn, "r"); + FILE *fp = BLI_fopen(fn, "r"); if (fp) { py_dict = PyC_DefaultNameSpace(fn); diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c index 839963e12b9..6b625d1a59a 100644 --- a/source/blender/render/intern/source/voxeldata.c +++ b/source/blender/render/intern/source/voxeldata.c @@ -342,7 +342,7 @@ void cache_voxeldata(Tex *tex, int scene_frame) case TEX_VD_BLENDERVOXEL: BLI_path_abs(path, G.main->name); if (!BLI_exists(path)) return; - fp = fopen(path,"rb"); + fp = BLI_fopen(path,"rb"); if (!fp) return; if(read_voxeldata_header(fp, vd)) @@ -353,7 +353,7 @@ void cache_voxeldata(Tex *tex, int scene_frame) case TEX_VD_RAW_8BIT: BLI_path_abs(path, G.main->name); if (!BLI_exists(path)) return; - fp = fopen(path,"rb"); + fp = BLI_fopen(path,"rb"); if (!fp) return; load_frame_raw8(vd, fp, curframe); diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt index 521074463e0..2a1a1d5649d 100644 --- a/source/blender/windowmanager/CMakeLists.txt +++ b/source/blender/windowmanager/CMakeLists.txt @@ -136,4 +136,10 @@ if(WITH_BUILDINFO) add_definitions(-DWITH_BUILDINFO) endif() +if(WIN322) + list(APPEND INC + ../../../intern/utfconv + ) +endif() + blender_add_lib_nolist(bf_windowmanager "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/windowmanager/SConscript b/source/blender/windowmanager/SConscript index be037452284..ddb61d721cc 100644 --- a/source/blender/windowmanager/SConscript +++ b/source/blender/windowmanager/SConscript @@ -32,6 +32,7 @@ if env['OURPLATFORM'] == 'linux': if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): incs += ' ' + env['BF_PTHREADS_INC'] + incs += ' ../../intern/utfconv' if env['OURPLATFORM'] != 'darwin' or env['WITH_GHOST_COCOA']: sources.remove('intern' + os.sep + 'wm_apple.c') diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 1e2c48f4e7f..5384d6ef8f7 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -304,6 +304,7 @@ static void wm_init_userdef(bContext *C) #define BKE_READ_EXOTIC_OK_BLEND 0 /* .blend file */ #define BKE_READ_EXOTIC_OK_OTHER 1 /* other supported formats */ + /* intended to check for non-blender formats but for now it only reads blends */ static int wm_read_exotic(Scene *UNUSED(scene), const char *name) { @@ -319,8 +320,7 @@ static int wm_read_exotic(Scene *UNUSED(scene), const char *name) retval= BKE_READ_EXOTIC_FAIL_PATH; } else { - gzfile = gzopen(name,"rb"); - + gzfile = BLI_gzopen(name,"rb"); if (gzfile == NULL) { retval= BKE_READ_EXOTIC_FAIL_OPEN; } @@ -627,7 +627,7 @@ static void write_history(void) recent = G.recent_files.first; /* refresh recent-files.txt of recent opened files, when current file was changed */ if(!(recent) || (BLI_path_cmp(recent->filepath, G.main->name)!=0)) { - fp= fopen(name, "w"); + fp= BLI_fopen(name, "w"); if (fp) { /* add current file to the beginning of list */ recent = (RecentFile*)MEM_mallocN(sizeof(RecentFile),"RecentFile"); diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index a4aec7d7ba3..57c62db3117 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -40,6 +40,10 @@ blender_include_dirs( ../blender/windowmanager ) +if(WIN32) + blender_include_dirs(../../intern/utfconv) +endif() + if(WITH_LIBMV) blender_include_dirs(../../extern/libmv) add_definitions(-DWITH_LIBMV) @@ -823,6 +827,7 @@ endif() bf_intern_memutil bf_intern_guardedalloc bf_intern_ctr + bf_intern_utfconv ge_blen_routines ge_converter ge_phys_dummy diff --git a/source/creator/creator.c b/source/creator/creator.c index eb5761bb095..63e25e1d820 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -40,6 +40,11 @@ #include <xmmintrin.h> #endif +#ifdef WIN32 +#include <Windows.h> +#include "utfconv.h" +#endif + #include <stdlib.h> #include <stddef.h> #include <string.h> @@ -1109,12 +1114,28 @@ char **environ = NULL; #endif + +#ifdef WIN32 +int main(int argc, const char **argv_c) /*Do not mess with const*/ +#else int main(int argc, const char **argv) +#endif { SYS_SystemHandle syshandle; bContext *C= CTX_create(); bArgs *ba; +#ifdef WIN32 + wchar_t ** argv_16 = CommandLineToArgvW(GetCommandLineW(), &argc); + int argci = 0; + char ** argv = MEM_mallocN(argc * sizeof(char*),"argv array"); + for(argci=0; argci<argc; argci++) + { + argv[argci] = alloc_utf_8_from_16(argv_16[argci],0); + } + LocalFree(argv_16); +#endif + #ifdef WITH_PYTHON_MODULE #ifdef __APPLE__ environ = *_NSGetEnviron(); @@ -1124,6 +1145,8 @@ int main(int argc, const char **argv) evil_C= C; #endif + + #ifdef WITH_BINRELOC br_init( NULL ); #endif @@ -1245,6 +1268,15 @@ int main(int argc, const char **argv) BLI_argsFree(ba); +#ifdef WIN32 + while(argci) + { + free(argv[--argci]); + } + MEM_freeN(argv); + argv = NULL; +#endif + #ifdef WITH_PYTHON_MODULE return 0; /* keep blender in background mode running */ #endif |