Added Unicode support for the Windows command line tools.
parent
2671205bcb
commit
5a423d124c
|
@ -85,8 +85,13 @@ endif()
|
|||
# Additional files to add to main executables
|
||||
if(APPLE)
|
||||
set(MTS_DARWIN_STUB "${CMAKE_CURRENT_SOURCE_DIR}/src/mitsuba/darwin_stub.mm")
|
||||
set(MTS_WINDOWS_STUB "")
|
||||
elseif(WIN32)
|
||||
set(MTS_DARWIN_STUB "")
|
||||
set(MTS_WINDOWS_STUB "${CMAKE_CURRENT_SOURCE_DIR}/data/windows/wmain_stub.cpp")
|
||||
else()
|
||||
set(MTS_DARWIN_STUB "")
|
||||
set(MTS_WINDOWS_STUB "")
|
||||
endif()
|
||||
|
||||
|
||||
|
|
|
@ -6,9 +6,10 @@ import os
|
|||
resources = []
|
||||
plugins = []
|
||||
stubs = []
|
||||
winstubs = []
|
||||
|
||||
Export('SCons', 'sys', 'os', 'glob', 'resources',
|
||||
'plugins', 'stubs')
|
||||
'plugins', 'stubs', 'winstubs')
|
||||
|
||||
# Configure the build framework
|
||||
env = SConscript('build/SConscript.configure')
|
||||
|
@ -18,6 +19,9 @@ Export('env')
|
|||
if sys.platform == 'win32':
|
||||
# Set an application icon on Windows
|
||||
resources += [ env.RES('data/windows/mitsuba_res.rc') ]
|
||||
# Convert the command line args from UTF-8 to UTF-16
|
||||
winstubs += [os.path.abspath('data/windows/wmain_stub.cpp')]
|
||||
Export('winstubs')
|
||||
|
||||
def build(scriptFile, exports = [], duplicate = 0):
|
||||
dirname = '/'.join(os.path.dirname(scriptFile).split('/')[1:])
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
This file is part of Mitsuba, a physically based rendering system.
|
||||
|
||||
Copyright (c) 2007-2012 by Wenzel Jakob and others.
|
||||
|
||||
Mitsuba is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License Version 3
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
Mitsuba 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <mitsuba/core/platform.h>
|
||||
#if defined(__WINDOWS__)
|
||||
|
||||
// Stub for generating UTF-8 command line arguments from wmain (UTF-16)
|
||||
#include <Windows.h>
|
||||
|
||||
extern int mts_main(int argc, char **argv);
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class ArgsUTF8 {
|
||||
public:
|
||||
ArgsUTF8(int argc, wchar_t *wargv[]) :
|
||||
m_argc(-1), m_argv(NULL), m_data(NULL)
|
||||
{
|
||||
if (argc > 0)
|
||||
m_argc = argc;
|
||||
else
|
||||
return;
|
||||
|
||||
m_argv = new char*[argc];
|
||||
int total = 0;
|
||||
|
||||
// Pass 1: get the lengths of each converted string an allocate data
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
const int lenUtf8 = WideCharToMultiByte(CP_UTF8, 0,
|
||||
wargv[i], -1, NULL, 0, NULL, NULL);
|
||||
if (lenUtf8 != 0) {
|
||||
total += lenUtf8;
|
||||
m_argv[i] = reinterpret_cast<char*>(lenUtf8);
|
||||
} else {
|
||||
m_argc = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_argc < 1)
|
||||
return;
|
||||
|
||||
m_data = new char[total];
|
||||
int currOffset = 0;
|
||||
|
||||
// Pass 2: perform the conversion
|
||||
for (int i = 0; i < m_argc; ++i) {
|
||||
int lenUtf8 = reinterpret_cast<int>(m_argv[i]);
|
||||
m_argv[i] = m_data + currOffset;
|
||||
lenUtf8 = WideCharToMultiByte(CP_UTF8, 0,
|
||||
wargv[i], -1, m_argv[i], lenUtf8, NULL, NULL);
|
||||
if (lenUtf8 != 0) {
|
||||
currOffset += lenUtf8;
|
||||
} else {
|
||||
m_argc = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~ArgsUTF8() {
|
||||
if (m_argv != NULL) {
|
||||
delete [] m_argv;
|
||||
}
|
||||
if (m_data != NULL) {
|
||||
delete [] m_data;
|
||||
}
|
||||
}
|
||||
|
||||
inline int argc() const {
|
||||
return m_argc;
|
||||
}
|
||||
|
||||
inline char** argv() const {
|
||||
return m_argv;
|
||||
}
|
||||
|
||||
private:
|
||||
int m_argc;
|
||||
char** m_argv;
|
||||
char* m_data;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
// MSDN Documentation:
|
||||
// http://msdn.microsoft.com/en-US/library/fzc2cy7w%28v=vs.110%29.aspx
|
||||
int wmain(int argc, wchar_t *wargv[], wchar_t *envp[]) {
|
||||
ArgsUTF8 argsUTF8(argc, wargv);
|
||||
return mts_main(argsUTF8.argc(), argsUTF8.argv());
|
||||
}
|
||||
|
||||
#endif // __WINDOWS__
|
|
@ -25,5 +25,5 @@ target_link_libraries(mtsconverter_lib
|
|||
${COLLADA_LIBRARIES} ${XERCES_LIBRARIES} ${OPENGL_glu_LIBRARY})
|
||||
|
||||
add_mts_exe(mtsimport mtsimport.cpp ${SRCS}
|
||||
${MTS_DARWIN_STUB} LINK_LIBRARIES mtsconverter_lib
|
||||
${MTS_DARWIN_STUB} ${MTS_WINDOWS_STUB} LINK_LIBRARIES mtsconverter_lib
|
||||
RES_DESCRIPTION "Mitsuba COLLADA 1.4 & Wavefront OBJ importer")
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Import('mainEnv', 'hasCollada', 'stubs')
|
||||
Import('mainEnv', 'hasCollada', 'stubs', 'winstubs')
|
||||
|
||||
converter_objects = []
|
||||
|
||||
|
@ -18,7 +18,7 @@ if hasCollada:
|
|||
colladaEnv.StaticObject('obj.cpp'),
|
||||
colladaEnv.StaticObject('converter.cpp')
|
||||
]
|
||||
colladaEnv.Program('mtsimport', stubs + ['mtsimport.cpp']
|
||||
colladaEnv.Program('mtsimport', stubs + winstubs + ['mtsimport.cpp']
|
||||
+ converter_objects)
|
||||
|
||||
Return('converter_objects')
|
||||
|
|
|
@ -241,7 +241,7 @@ int mts_main(int argc, char **argv) {
|
|||
return retval;
|
||||
}
|
||||
|
||||
#if !defined(__OSX__)
|
||||
#if !defined(__OSX__) && !defined(__WINDOWS__)
|
||||
int main(int argc, char **argv) {
|
||||
return mts_main(argc, argv);
|
||||
}
|
||||
|
|
|
@ -5,9 +5,9 @@ endif()
|
|||
|
||||
include_directories(${XERCES_INCLUDE_DIRS})
|
||||
|
||||
add_mts_exe(mtssrv mtssrv.cpp
|
||||
add_mts_exe(mtssrv mtssrv.cpp ${MTS_WINDOWS_STUB}
|
||||
RES_DESCRIPTION "Mitsuba compute node application")
|
||||
add_mts_exe(mitsuba mitsuba.cpp
|
||||
add_mts_exe(mitsuba mitsuba.cpp ${MTS_WINDOWS_STUB}
|
||||
RES_DESCRIPTION "Mitsuba command line interface frontend")
|
||||
add_mts_exe(mtsutil mtsutil.cpp ${MTS_DARWIN_STUB}
|
||||
add_mts_exe(mtsutil mtsutil.cpp ${MTS_DARWIN_STUB} ${MTS_WINDOWS_STUB}
|
||||
RES_DESCRIPTION "Mitsuba utility launcher")
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Import('sys', 'env', 'hasCollada', 'stubs')
|
||||
Import('sys', 'env', 'hasCollada', 'stubs', 'winstubs')
|
||||
|
||||
# Create an environment with Xerces and OpenGL
|
||||
mainEnv = env.Clone()
|
||||
|
@ -24,10 +24,10 @@ if sys.platform == 'darwin':
|
|||
stubs += [mainEnv_osx.StaticObject('darwin_stub.mm')]
|
||||
mainEnv.Append(LINKFLAGS=['-Xlinker', '-rpath', '-Xlinker', '@executable_path/../Frameworks'])
|
||||
|
||||
mainEnv.Program('mtsutil', stubs + ['mtsutil.cpp'])
|
||||
mainEnv.Program('mtsutil', stubs + winstubs + ['mtsutil.cpp'])
|
||||
|
||||
# Build the command-line+GUI interface
|
||||
mainEnv.Program('mtssrv', ['mtssrv.cpp'])
|
||||
mainEnv.Program('mitsuba', ['mitsuba.cpp'])
|
||||
mainEnv.Program('mtssrv', winstubs + ['mtssrv.cpp'])
|
||||
mainEnv.Program('mitsuba', winstubs + ['mitsuba.cpp'])
|
||||
|
||||
Return('mainEnv')
|
||||
|
|
|
@ -124,7 +124,7 @@ private:
|
|||
int m_timeout;
|
||||
};
|
||||
|
||||
int mts_main(int argc, char **argv) {
|
||||
int mitsuba_app(int argc, char **argv) {
|
||||
char optchar, *end_ptr = NULL;
|
||||
|
||||
try {
|
||||
|
@ -397,7 +397,7 @@ int mts_main(int argc, char **argv) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int mts_main(int argc, char **argv) {
|
||||
/* Initialize the core framework */
|
||||
Class::staticInitialization();
|
||||
Object::staticInitialization();
|
||||
|
@ -426,7 +426,7 @@ int main(int argc, char **argv) {
|
|||
setlocale(LC_NUMERIC, "C");
|
||||
#endif
|
||||
|
||||
int retval = mts_main(argc, argv);
|
||||
int retval = mitsuba_app(argc, argv);
|
||||
|
||||
/* Shutdown the core framework */
|
||||
SceneHandler::staticShutdown();
|
||||
|
@ -449,3 +449,9 @@ int main(int argc, char **argv) {
|
|||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#if !defined(__WINDOWS__)
|
||||
int main(int argc, char **argv) {
|
||||
return mts_main(argc, argv);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -90,7 +90,7 @@ void collect_zombies(int s) {
|
|||
}
|
||||
#endif
|
||||
|
||||
int mts_main(int argc, char **argv) {
|
||||
int mtssrv(int argc, char **argv) {
|
||||
char optchar, *end_ptr = NULL;
|
||||
|
||||
try {
|
||||
|
@ -382,7 +382,7 @@ int mts_main(int argc, char **argv) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int mts_main(int argc, char **argv) {
|
||||
/* Initialize the core framework */
|
||||
Class::staticInitialization();
|
||||
Object::staticInitialization();
|
||||
|
@ -409,7 +409,7 @@ int main(int argc, char **argv) {
|
|||
setlocale(LC_NUMERIC, "C");
|
||||
#endif
|
||||
|
||||
int retval = mts_main(argc, argv);
|
||||
int retval = mtssrv(argc, argv);
|
||||
|
||||
/* Shutdown the core framework */
|
||||
SHVector::staticShutdown();
|
||||
|
@ -432,3 +432,9 @@ int main(int argc, char **argv) {
|
|||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#if !defined(__WINDOWS__)
|
||||
int main(int argc, char **argv) {
|
||||
return mts_main(argc, argv);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -435,10 +435,8 @@ int mts_main(int argc, char **argv) {
|
|||
return retval;
|
||||
}
|
||||
|
||||
#if !defined(__OSX__)
|
||||
#if !defined(__OSX__) && !defined(__WINDOWS__)
|
||||
int main(int argc, char **argv) {
|
||||
return mts_main(argc, argv);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue