Adds support for utf paths on Windows.
authorAlexander Kuznetsov <kuzsasha@gmail.com>
Tue, 20 Mar 2012 02:17:37 +0000 (02:17 +0000)
committerAlexander Kuznetsov <kuzsasha@gmail.com>
Tue, 20 Mar 2012 02:17:37 +0000 (02:17 +0000)
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:
build_files/scons/tools/Blender.py
intern/CMakeLists.txt
intern/SConscript
intern/ghost/CMakeLists.txt
intern/ghost/SConscript
intern/ghost/intern/GHOST_DropTargetWin32.cpp
intern/ghost/intern/GHOST_SystemPathsWin32.cpp
intern/ghost/intern/GHOST_SystemWin32.cpp
intern/ghost/intern/GHOST_WindowWin32.cpp
intern/ghost/intern/GHOST_WindowWin32.h
intern/utfconv/CMakeLists.txt [new file with mode: 0644]
intern/utfconv/SConscript [new file with mode: 0644]
intern/utfconv/utf_winfunc.c [new file with mode: 0644]
intern/utfconv/utf_winfunc.h [new file with mode: 0644]
intern/utfconv/utfconv.c [new file with mode: 0644]
intern/utfconv/utfconv.h [new file with mode: 0644]
source/blender/blenkernel/intern/blender.c
source/blender/blenkernel/intern/customdata_file.c
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/movieclip.c
source/blender/blenkernel/intern/packedFile.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenkernel/intern/pointcache.c
source/blender/blenkernel/intern/text.c
source/blender/blenlib/BLI_fileops.h
source/blender/blenlib/BLI_winstuff.h
source/blender/blenlib/CMakeLists.txt
source/blender/blenlib/SConscript
source/blender/blenlib/intern/dynlib.c
source/blender/blenlib/intern/fileops.c
source/blender/blenlib/intern/path_util.c
source/blender/blenlib/intern/storage.c
source/blender/blenlib/intern/winstuff.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/runtime.c
source/blender/blenloader/intern/writefile.c
source/blender/editors/armature/reeb.c
source/blender/editors/curve/editfont.c
source/blender/editors/physics/physics_fluid.c
source/blender/editors/space_file/fsmenu.c
source/blender/editors/space_text/text_ops.c
source/blender/imbuf/CMakeLists.txt
source/blender/imbuf/SConscript
source/blender/imbuf/intern/bmp.c
source/blender/imbuf/intern/cineon/cineonlib.c
source/blender/imbuf/intern/cineon/dpxlib.c
source/blender/imbuf/intern/cineon/logImageLib.c
source/blender/imbuf/intern/indexer.c
source/blender/imbuf/intern/iris.c
source/blender/imbuf/intern/jp2.c
source/blender/imbuf/intern/jpeg.c
source/blender/imbuf/intern/png.c
source/blender/imbuf/intern/radiance_hdr.c
source/blender/imbuf/intern/readimage.c
source/blender/imbuf/intern/targa.c
source/blender/imbuf/intern/thumbs.c
source/blender/imbuf/intern/thumbs_blend.c
source/blender/imbuf/intern/util.c
source/blender/modifiers/intern/MOD_fluidsim_util.c
source/blender/python/intern/bpy_interface.c
source/blender/render/intern/source/voxeldata.c
source/blender/windowmanager/CMakeLists.txt
source/blender/windowmanager/SConscript
source/blender/windowmanager/intern/wm_files.c
source/creator/CMakeLists.txt
source/creator/creator.c

index d806b14deea1ef04d85f91336af429ab69ef19b7..155b4e800bb11a879fc4763b328484265f67fbbf 100644 (file)
@@ -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)
index 9f5217e68e3098e005a11db33609f7bf62fb4f57..5637fa383a1b8439c4647adeca95ed8872db3900 100644 (file)
@@ -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
index bb19426263a7ff19be0483d9221e967cc7a08c7a..196a80433c95c002a45b6b42b09e86a5042af08e 100644 (file)
@@ -3,6 +3,7 @@ Import ('env')
 
 SConscript(['audaspace/SConscript',
             'string/SConscript',
+                       'utfconv/SConscript',
             'ghost/SConscript',
             'guardedalloc/SConscript',
             'moto/SConscript',
index 5693aea08658c14a80ce8e78dfa4228a37c225a7..5c653ac92c01d4aa3c48b40357321429a0f499da 100644 (file)
@@ -281,6 +281,10 @@ elseif(WIN32)
                ${WINTAB_INC}
        )
 
+       list(APPEND INC
+               ../utfconv
+       )
+
        list(APPEND SRC
                intern/GHOST_DisplayManagerWin32.cpp
                intern/GHOST_SystemWin32.cpp
index 3410f11a97176ecb3c8ed58d2aacac9e61bf4d6a..2265daa8fffff69ed0d3d4d1f3392808e7a56101 100644 (file)
@@ -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') )
index 4c9072d2ce6334579783e99e03cfa228234e1cc9..c13c242bc7e9b7376f5a6beb2d30ad426fe4c4a3 100644 (file)
@@ -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;
index 379e1963c40900a9fd849db42671d29ec0afc8fd..29c2e9c02279a347074920d3e51b854952b688d5 100644 (file)
@@ -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)
 }
index b478fea706cb7f67d25faacf86756e14a92ea40e..b79185b163790786fb61365acb2d771e4703aef6 100644 (file)
@@ -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);
                }
index 8e37d1832dffcd73aa75b03525c3987a83eb382c..9d105748095bf8427affcd5f62e172e12493add4 100644 (file)
@@ -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;
index 6eb17affdbf626cd9e8784bc1020da25eaf46d87..c8e88c8d8446bda9aefad146ac10e9a5c6a8d6ed 100644 (file)
@@ -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 (file)
index 0000000..9dd41c2
--- /dev/null
@@ -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 (file)
index 0000000..1f0fab3
--- /dev/null
@@ -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 (file)
index 0000000..09f5dff
--- /dev/null
@@ -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 (file)
index 0000000..5e88d2d
--- /dev/null
@@ -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 (file)
index 0000000..9aeca36
--- /dev/null
@@ -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 (file)
index 0000000..185c764
--- /dev/null
@@ -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
index 30f4e9f2816793b81b2abba9d14e91a2f14247db..2ef93dd7fa3749d7aaea6d8c1ada76f4b4707606 100644 (file)
@@ -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;
index 4386132fc1829d10e926ce26cac7d2af0e9cffc1..5538267a5f1973e06bc5fabc39d91e7dc1f9247e 100644 (file)
@@ -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;
        
index 4300995b68c2501385baabcffb42e68c01c64df7..053ebf654f056f6219893d7e4c1827fdce255e22 100644 (file)
@@ -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);
        
index 0af6b9dd219516e54edcb8e54c1f4b1c7c6ff628..1b415f1654f3f39992bfdf9a478672328cd7ba72 100644 (file)
@@ -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);
 
index 4230510dac916e0116d20c2b23a71364403e10a4..64ccdf9b8437aad9f90350c513d2977ae2b93d77 100644 (file)
@@ -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 {
index a0668d621e8cafac1b6e66292ad435a8102ccb0d..978971a04a41be6e4fea3c768992e120e848f587 100644 (file)
@@ -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);
index 69e96c7a69806657b4fda7bf28d749c116f4b993..a2425b0a3ac9483572702afb1d6b81946bfb4150 100644 (file)
@@ -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)
index ffb8e830ed46957ff1c222fe7deba426e7539cbf..66759edde658552984be4268a34cae9301b12a2c 100644 (file)
@@ -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));
index 8fe8456e845a46277887b04db7775cfef8467064..fa1a61998d79de342bc3527db6b2a72d353f8184 100644 (file)
@@ -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);
 
index d939882b1055448a5fd2850e0ac283df9f08fc3f..c393b219785989c760ce6312eab4a81a0ddd1e0a 100644 (file)
@@ -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;
index ddcc344e9393d80111123a96c00a03e156f52964..c06a124072966c9edda1daa18713559216ae4c83 100644 (file)
@@ -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}")
index dda8303eea77e05f4351a0286281c29658768abe..ea51e5b6ab511baa3cd775e6789232858329441c 100644 (file)
@@ -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']:
index 0bfa5e79eb8257bbdf39979bc5adb3800a06fb56..c23feb975dfe3ebfe22fb7287e2227bc5237cde6 100644 (file)
@@ -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;
index ab7beeeb8f1c213d43dc00d74f4cc741cd0cd17c..9527ec9466bafd31c9be8f89216f5f2ffb946244 100644 (file)
@@ -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, '"')) {
index 9c80fa9ca15a50ac140433e74b62b16da469f7bc..ccf85934788a0e587ef2d707244db4b9c7037f1e 100644 (file)
@@ -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]= "";
index 29f11ee05500a6e096cc8ad6d991b46ddd9aabdf..363052c7255d63e545d58b1d1511e9e7785411cb 100644 (file)
@@ -78,6 +78,7 @@
 #include <io.h>
 #include <direct.h>
 #include "BLI_winstuff.h"
+#include "utfconv.h"
 #endif
 
 
 
 #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);
 }
 
index 4665b08b20209919246bca7a6e16d3684f860edd..7fc2e52255ca79e26feee5e8f162a122234e86b9 100644 (file)
 #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 {
index 95a76dac6167c82d4595a9ebf63a83dfb386a914..7a6e23cd5bba27a411718f9af11e7827b4484f1f 100644 (file)
@@ -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");
index 3f8a9807f18b6b03d2cd52e7dca9616f658fc301..88f602641ffa91ea1a0036ad6fa35ab0f5c674ca 100644 (file)
@@ -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));
index 8cd6712c5604194c98762436274a64eb34a586d4..02de7a371ffc66a73ed57e282f5c75044a80ed77 100644 (file)
@@ -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;
index bb24a1d8412afae7c1040681bfc3924ac6be83dd..e832247e67c83338cdfc223f210daa815947a411 100644 (file)
@@ -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)
        {
index efde93b4ad70f2dca352b59f54d9e46e974cf93a..4170b7e3299267f23f757d944a3808aede7c54a2 100644 (file)
@@ -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)
index dbdee3baca873a7e1aaa74d7c0a55e1bd07a95a6..43b1a4517adddbc9f91c0fcd150eb44b647564f7 100644 (file)
@@ -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
index 4c9d2be791b91dc195749e0e6e18d9e4d8a914b1..8b98b942f42ee11451fb553196c770af8088ac5f 100644 (file)
@@ -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 */
index 2f6e5082fdcb1e048f3c1458fa723c77a17ce51f..4c6357f7505bce2b455f13ab74f6ad5784d27fa3 100644 (file)
@@ -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;
index 649b7cb1c11f38a26fdaba208b988f3dc9bab840..aa4454562b443d1279e92c279e59a69b6f2ce954 100644 (file)
@@ -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}")
index ca56003845f5adaf5bf36626d3f9ba4262ce8dbb..b2b526ca17d76b064cccee6b4ff61581ba94f09a 100644 (file)
@@ -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')
index 1b6184c8b58502dfcf14caa45692940d1d77f085..1e13f5d913b256fe1b42e74da370cd92b0cc794c 100644 (file)
@@ -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" */
index 810ed7b26a4f0ca68b51f73b2ff505cac6ab98c2..a10d8c670517527ac535b56f32e513cbd8c30c3b 100644 (file)
@@ -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);
index a63a2ea1dab7a55eed7db0655ec3ea1ddff3513d..01177b01178bc24ccdb661d2cc8f3a5b0f3aa439 100644 (file)
@@ -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;
index 123d0b429796ffb1d388297d71720a5511a20079..dc50d93bf18512a492223c1ebbf03cb5d673d7a7 100644 (file)
@@ -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;
        }
index cf354371ddca810eba364b516b4ecf7ecdc14e65..dcbce6d028c8381c7752b25bde836f44c3aa48cc 100644 (file)
@@ -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);
index 83351b5e0e417014efa1ac136b64a6168d0ca0ad..38fc6f92c83bf7f0f08dfc5c6ad58974add2ca09 100644 (file)
@@ -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);
index c2bdb44be10b92ff3c2c47394cfc4168e54fe8de..87450170c6613913f86d2665db998bf13b6b7c89 100644 (file)
@@ -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);
index 2aab497649a0996c1a10a368876d997ec8bb4c3f..75a5f27441393cd6de58b088b0187a7bdf7de28c 100644 (file)
@@ -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);
index 84f3e18591dad7851f3c510bd136ece19a1583e9..78c7c672e22c30a84cf0bb94564f86ab78c5bdd3 100644 (file)
@@ -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);
index 9265da8d8dc8bd23654159f4de796fdacfc3f9d4..42e4db54f3f24d2e29e6e1bd4838ace507e760f9 100644 (file)
@@ -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;
index c2f73efa63fc0c7d3121e0c1a138eb1b2227197c..2ee389a42f634245164e6297c75f613c771b1e12 100644 (file)
@@ -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);
index b5552a174a9ff343eb958706a5c032a79cbb81ed..1801c1a8ef9615473caa7fc5e97d5554c88bdef8 100644 (file)
@@ -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) {
index fdc9e50bcd8421b92de0284e4645b0b0c312f7bb..be716870dadcb2707401acd57e1a8684bc1b36e0 100644 (file)
@@ -61,6 +61,7 @@
 #include <process.h> /* getpid */
 #include <direct.h> /* chdir */
 #include "BLI_winstuff.h"
+#include "utfconv.h"
 #else
 #include <unistd.h>
 #endif
 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;
index 1068eccc6e04becd4612e69759063cc010f9a4d0..fd0be89df0da8cce94c7b04726f01853977e6d25 100644 (file)
@@ -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;
index b7eba1002c53bbae72402a8c926c1a2c0c6f5184..fdcc0641628c16f7ef5a755f3e6fff48872793d0 100644 (file)
@@ -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) {
index 31a50a6a16bfc933472ca1fc1ee4ebb18fafad6d..2ccae9671b3e3c1c0ba54fca05319d3b8b5d5c38 100644 (file)
@@ -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);
index 52272bdb697f9a6f325f05feb50c40e7df5b8119..f3d21c74080b3e730ab771c52cd3f8b8b2070162 100644 (file)
@@ -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);
index 839963e12b9917313451531d0da318b5a8ed45e5..6b625d1a59aa3f1cc81066949fe954240a80924d 100644 (file)
@@ -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);
index 521074463e0668787b7ccef8f4788e5755947f0c..2a1a1d5649d33379c2f74a3fb17ba179826d5869 100644 (file)
@@ -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}")
index be037452284eac8a56be53d3263592c8d4086911..ddb61d721cc15e337ff0ad1f2e80ff8602ded3ca 100644 (file)
@@ -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')
index 1e2c48f4e7f84185a8009729ea9521c92eea74f8..5384d6ef8f7a67df525781422c379d6644bdf58c 100644 (file)
@@ -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");
index a4aec7d7ba358905ad76fd0d8bb97dbfecec499d..57c62db3117091f8c4ec28d12fe02c62ec7d3163 100644 (file)
@@ -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
index eb5761bb0955724b53ea76ec7123414924108fa9..63e25e1d820751624d449f47c4f648199ecae12e 100644 (file)
 #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