X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fsupport%2Fos_win32.cpp;h=0928259b72dd47fa9de466d4ca2ccec86450bc0d;hb=12554c93d81f75f87c34040fd7737048d3518d6d;hp=72612e2b6e576de8b5a3a4f10f5a6c055fa13d2e;hpb=220f0f9f5ba510a9f1e30315b1f44401c1b92484;p=lyx.git diff --git a/src/support/os_win32.cpp b/src/support/os_win32.cpp index 72612e2b6e..0928259b72 100644 --- a/src/support/os_win32.cpp +++ b/src/support/os_win32.cpp @@ -6,6 +6,7 @@ * \author Ruurd A. Reitsma * \author Claus Hentschel * \author Angus Leeming + * \author Enrico Forestieri * * Full author contact details are available in file CREDITS. * @@ -14,10 +15,13 @@ #include +#include "LyXRC.h" + #include "support/os.h" #include "support/os_win32.h" #include "support/debug.h" +#include "support/environment.h" #include "support/FileName.h" #include "support/gettext.h" #include "support/filetools.h" @@ -32,25 +36,6 @@ #include -/* The GetLongPathName macro may be defined on the compiling machine, - * but we must use a bit of trickery if the resulting executable is - * to run on a Win95 machine. - * Fortunately, Microsoft provide the trickery. All we need is the - * NewAPIs.h header file, available for download from Microsoft as - * part of the Platform SDK. - */ -#if defined (HAVE_NEWAPIS_H) -// This should be defined already to keep Boost.Filesystem happy. -# if !defined (WANT_GETFILEATTRIBUTESEX_WRAPPER) -# error Expected WANT_GETFILEATTRIBUTESEX_WRAPPER to be defined! -# endif -# define WANT_GETLONGPATHNAME_WRAPPER 1 -# define COMPILE_NEWAPIS_STUBS -# include -# undef COMPILE_NEWAPIS_STUBS -# undef WANT_GETLONGPATHNAME_WRAPPER -#endif - #include #include // _getdrive #include // SHGetFolderPath @@ -71,6 +56,16 @@ #define ASSOCF_INIT_IGNOREUNKNOWN 0 #endif +#if defined(__MINGW32__) +#include +#endif + + +extern "C" { +extern void __wgetmainargs(int * argc, wchar_t *** argv, wchar_t *** envp, + int expand_wildcards, int * new_mode); +} + using namespace std; namespace lyx { @@ -82,6 +77,9 @@ namespace os { namespace { +int argc_ = 0; +wchar_t ** argv_ = 0; + bool windows_style_tex_paths_ = true; string cygdrive = "/cygdrive"; @@ -99,7 +97,7 @@ BOOL terminate_handler(DWORD event) } // namespace anon -void init(int /* argc */, char * argv[]) +void init(int argc, char * argv[]) { /* Note from Angus, 17 Jan 2005: * @@ -157,6 +155,13 @@ void init(int /* argc */, char * argv[]) * lyx is invoked as a parameter of hidecmd.exe. */ + + // Get the wide program arguments array + wchar_t ** envp = 0; + int newmode = 0; + __wgetmainargs(&argc_, &argv_, &envp, -1, &newmode); + LATTEST(argc == argc_); + // If Cygwin is detected, query the cygdrive prefix. // The cygdrive prefix is needed for translating windows style paths // to posix style paths in LaTeX files when the Cygwin teTeX is used. @@ -205,6 +210,21 @@ void init(int /* argc */, char * argv[]) } +string utf8_argv(int i) +{ + LASSERT(i < argc_, return ""); + return fromqstr(QString::fromWCharArray(argv_[i])); +} + + +void remove_internal_args(int i, int num) +{ + argc_ -= num; + for (int j = i; j < argc_; ++j) + argv_[j] = argv_[j + num]; +} + + string current_root() { // _getdrive returns the current drive (1=A, 2=B, and so on). @@ -292,16 +312,25 @@ static QString const get_long_path(QString const & short_path) long_path.resize(result); result = GetLongPathNameW((wchar_t *) short_path.utf16(), &long_path[0], long_path.size()); - LASSERT(result <= long_path.size(), /**/); + LATTEST(result <= long_path.size()); } return (result == 0) ? short_path : QString::fromWCharArray(&long_path[0]); } -static QString const get_short_path(QString const & long_path) +static QString const get_short_path(QString const & long_path, file_access how) { - // GetShortPathNameW needs the path in utf16 encoding. + // CreateFileW and GetShortPathNameW need the path in utf16 encoding. + if (how == CREATE) { + HANDLE h = CreateFileW((wchar_t *) long_path.utf16(), + GENERIC_WRITE, 0, NULL, CREATE_NEW, + FILE_ATTRIBUTE_NORMAL, NULL); + if (h == INVALID_HANDLE_VALUE + && GetLastError() != ERROR_FILE_EXISTS) + return long_path; + CloseHandle(h); + } vector short_path(MAX_PATH); DWORD result = GetShortPathNameW((wchar_t *) long_path.utf16(), &short_path[0], short_path.size()); @@ -310,7 +339,7 @@ static QString const get_short_path(QString const & long_path) short_path.resize(result); result = GetShortPathNameW((wchar_t *) long_path.utf16(), &short_path[0], short_path.size()); - LASSERT(result <= short_path.size(), /**/); + LATTEST(result <= short_path.size()); } return (result == 0) ? long_path : QString::fromWCharArray(&short_path[0]); @@ -323,9 +352,9 @@ string internal_path(string const & p) } -string safe_internal_path(string const & p) +string safe_internal_path(string const & p, file_access how) { - return subst(fromqstr(get_short_path(toqstr(p))), "\\", "/"); + return subst(fromqstr(get_short_path(toqstr(p), how)), "\\", "/"); } @@ -359,6 +388,38 @@ string latex_path(string const & p) } +string latex_path_list(string const & p) +{ + if (p.empty()) + return p; + + // We may need a posix style path or a windows style path (depending + // on windows_style_tex_paths_), but we use always forward slashes, + // since this is standard for all tex engines. + + if (!windows_style_tex_paths_) { + string pathlist; + for (size_t i = 0, k = 0; i != string::npos; k = i) { + i = p.find(';', i); + string path = subst(p.substr(k, i - k), '\\', '/'); + if (FileName::isAbsolute(path)) { + string const drive = path.substr(0, 2); + string const cygprefix = cygdrive + "/" + + drive.substr(0, 1); + path = subst(path, drive, cygprefix); + } + pathlist += path; + if (i != string::npos) { + pathlist += ':'; + ++i; + } + } + return pathlist; + } + return subst(p, '\\', '/'); +} + + bool is_valid_strftime(string const & p) { string::size_type pos = p.find_first_of('%'); @@ -391,34 +452,17 @@ string const & nulldev() } -bool is_terminal(io_channel channel) -{ - switch (channel) { - case STDIN: - if (GetStdHandle(STD_INPUT_HANDLE) == NULL) - return false; - break; - case STDOUT: - if (GetStdHandle(STD_OUTPUT_HANDLE) == NULL) - return false; - break; - case STDERR: - if (GetStdHandle(STD_ERROR_HANDLE) == NULL) - return false; - break; - } - return true; -} - - shell_type shell() { return CMD_EXE; } -char path_separator() +char path_separator(path_type type) { + if (type == TEXENGINE) + return windows_style_tex_paths_ ? ';' : ':'; + return ';'; } @@ -470,7 +514,7 @@ string const GetFolderPath::operator()(folder_id _id) const id = CSIDL_APPDATA; break; default: - LASSERT(false, /**/); + LASSERT(false, return string()); } HRESULT const result = (folder_path_func_)(0, id, 0, SHGFP_TYPE_CURRENT, @@ -495,12 +539,25 @@ bool canAutoOpenFile(string const & ext, auto_open_mode const mode) } -bool autoOpenFile(string const & filename, auto_open_mode const mode) +bool autoOpenFile(string const & filename, auto_open_mode const mode, + string const & path) { + string const texinputs = os::latex_path_list( + replaceCurdirPath(path, lyxrc.texinputs_prefix)); + string const sep = windows_style_tex_paths_ ? ";" : ":"; + string const oldval = getEnv("TEXINPUTS"); + string const newval = "." + sep + texinputs + sep + oldval; + if (!path.empty() && !lyxrc.texinputs_prefix.empty()) + setEnv("TEXINPUTS", newval); + // reference: http://msdn.microsoft.com/en-us/library/bb762153.aspx char const * action = (mode == VIEW) ? "open" : "edit"; - return reinterpret_cast(ShellExecute(NULL, action, + bool success = reinterpret_cast(ShellExecute(NULL, action, to_local8bit(from_utf8(filename)).c_str(), NULL, NULL, 1)) > 32; + + if (!path.empty() && !lyxrc.texinputs_prefix.empty()) + setEnv("TEXINPUTS", oldval); + return success; } @@ -597,7 +654,7 @@ string real_path(string const & path) CloseHandle(hmap); CloseHandle(hpath); string const retpath = subst(string(realpath), '\\', '/'); - return FileName::fromFilesystemEncoding(retpath).absFilename(); + return FileName::fromFilesystemEncoding(retpath).absFileName(); } } // namespace os