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 /intern/ghost | |
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.
Diffstat (limited to 'intern/ghost')
-rw-r--r-- | intern/ghost/CMakeLists.txt | 4 | ||||
-rw-r--r-- | intern/ghost/SConscript | 1 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_DropTargetWin32.cpp | 17 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemPathsWin32.cpp | 26 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWin32.cpp | 77 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowWin32.cpp | 22 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowWin32.h | 4 |
7 files changed, 98 insertions, 53 deletions
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 */ |