]> git.lyx.org Git - lyx.git/blobdiff - src/support/os_cygwin.C
* src/LaTeX.C (deplog): fix the regex to parse filenames in the log file
[lyx.git] / src / support / os_cygwin.C
index 0961606f1de2083cba2d508836558bb0daae877c..6cb2f22590d845b525cf67b41f2df618db674006 100644 (file)
 
 #include <windows.h>
 #include <io.h>
+#include <windef.h>
+#include <shellapi.h>  
+#include <shlwapi.h>
 
 #include <sys/cygwin.h>
 
 using std::endl;
 using std::string;
 
+using lyx::support::contains;
+
+#ifdef X_DISPLAY_MISSING
+#include "support/filetools.h"
+#include "support/package.h"
+#include "support/path.h"
+using lyx::support::addName;
+using lyx::support::addPath;
+using lyx::support::package;
+
+string const win_fonts_truetype[] = {"cmex10", "cmmi10", "cmr10", "cmsy10",
+       "eufm10", "msam10", "msbm10", "wasy10", "esint10"};
+const int num_fonts_truetype = sizeof(win_fonts_truetype) / sizeof(*win_fonts_truetype);
+#endif
+
 
 namespace lyx {
 namespace support {
 namespace os {
 
+namespace {
+
+bool windows_style_tex_paths_ = false;
+
+// In both is_posix_path() and is_windows_path() it is assumed that
+// a valid posix or pseudo-windows path is passed. They simply tell
+// whether the path looks posix/pseudo-windows or not.
+
+bool is_posix_path(string const & p)
+{
+       return  p.empty() ||
+               (!contains(p, '\\') && (p.length() <= 1 || p[1] != ':'));
+}
+
+// This is a test for a win32 style path with forward slashes (pseudo-windows).
+
+bool is_windows_path(string const & p)
+{
+       return p.empty() || (!contains(p, '\\') && p[0] != '/');
+}
+
+
+enum PathStyle {
+       posix,
+       windows
+};
+
+
+/// Convert a path to or from posix style.
+/// \p p is encoded in local 8bit encoding or utf8.
+/// The result is returned in the same encoding as \p p.
+string convert_path(string const & p, PathStyle const & target)
+{
+       char path_buf[PATH_MAX];
+
+       if ((target == posix && is_posix_path(p)) ||
+           (target == windows && is_windows_path(p)))
+               return p;
+
+       path_buf[0] = '\0';
+
+       // cygwin_conv_to_posix_path and cygwin_conv_to_win32_path do not
+       // care about the encoding.
+       if (target == posix)
+               cygwin_conv_to_posix_path(p.c_str(), path_buf);
+       else
+               cygwin_conv_to_win32_path(p.c_str(), path_buf);
+
+       return subst(path_buf[0] ? path_buf : p, '\\', '/');
+}
+
+
+/// Convert a path list to or from posix style.
+/// \p p is encoded in local 8bit encoding or utf8.
+/// The result is returned in the same encoding as \p p.
+string convert_path_list(string const & p, PathStyle const & target)
+{
+       if (p.empty())
+               return p;
+
+       char const * const pc = p.c_str();
+       PathStyle const actual = cygwin_posix_path_list_p(pc) ? posix : windows;
+
+       if (target != actual) {
+               int const target_size = (target == posix) ?
+                               cygwin_win32_to_posix_path_list_buf_size(pc) :
+                               cygwin_posix_to_win32_path_list_buf_size(pc);
+
+               char * ptr = new char[target_size];
+
+               if (ptr) {
+                       // FIXME: See comment in convert_path() above
+                       if (target == posix)
+                               cygwin_win32_to_posix_path_list(pc, ptr);
+                       else
+                               cygwin_posix_to_win32_path_list(pc, ptr);
+
+                       string path_list = subst(ptr, '\\', '/');
+                       delete ptr;
+                       return path_list;
+               }
+       }
+
+       return subst(p, '\\', '/');
+}
+
+} // namespace anon
+
 void os::init(int, char *[])
-{}
+{
+       // Copy cygwin environment variables to the Windows environment
+       // if they're not already there.
+
+       char **envp = environ;
+       char curval[2];
+       string var;
+       string val;
+       bool temp_seen = false;
+
+       while (envp && *envp) {
+               val = split(*envp++, var, '=');
+
+               if (var == "TEMP")
+                       temp_seen = true;
+               
+               if (GetEnvironmentVariable(var.c_str(), curval, 2) == 0
+                               && GetLastError() == ERROR_ENVVAR_NOT_FOUND) {
+                       /* Convert to Windows style where necessary */
+                       if (var == "PATH" || var == "LD_LIBRARY_PATH") {
+                               string const winpathlist =
+                                   convert_path_list(val, PathStyle(windows));
+                               if (!winpathlist.empty()) {
+                                       SetEnvironmentVariable(var.c_str(),
+                                               winpathlist.c_str());
+                               }
+                       } else if (var == "HOME" || var == "TMPDIR" ||
+                                       var == "TMP" || var == "TEMP") {
+                               string const winpath =
+                                       convert_path(val, PathStyle(windows));
+                               SetEnvironmentVariable(var.c_str(), winpath.c_str());
+                       } else {
+                               SetEnvironmentVariable(var.c_str(), val.c_str());
+                       }
+               }
+       }
+       if (!temp_seen) {
+               string const winpath = convert_path("/tmp", PathStyle(windows));
+               SetEnvironmentVariable("TEMP", winpath.c_str());
+       }
+}
 
 
 string current_root()
@@ -62,43 +208,46 @@ string::size_type common_path(string const & p1, string const & p2)
 }
 
 
-namespace {
-
-bool cygwin_path_fix_ = false;
-
-} // namespace anon
+string external_path(string const & p)
+{
+       return convert_path(p, PathStyle(posix));
+}
 
 
-string external_path(string const & p)
+string internal_path(string const & p)
 {
-       string dos_path;
+       return convert_path(p, PathStyle(posix));
+}
 
-       // Translate from cygwin path syntax to dos path syntax
-       if (cygwin_path_fix_ && is_absolute_path(p)) {
-               char dp[PATH_MAX];
-               cygwin_conv_to_full_win32_path(p.c_str(), dp);
-               dos_path = !dp ? "" : dp;
-       }
 
-       else return p;
+string external_path_list(string const & p)
+{
+       return convert_path_list(p, PathStyle(posix));
+}
 
-       //No backslashes in LaTeX files
-       dos_path = subst(dos_path,'\\','/');
 
-       lyxerr[Debug::LATEX]
-               << "<Cygwin path correction> ["
-               << p << "]->>["
-               << dos_path << ']' << endl;
-       return dos_path;
+string internal_path_list(string const & p)
+{
+       return convert_path_list(p, PathStyle(posix));
 }
 
 
-string internal_path(string const & p)
+string latex_path(string const & p)
 {
-       char posix_path[PATH_MAX];
-       posix_path[0] = '\0';
-       cygwin_conv_to_posix_path(p.c_str(), posix_path);
-       return posix_path;
+       // 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 it gets written into a .tex file.
+
+       if (windows_style_tex_paths_ && is_absolute_path(p)) {
+               string dos_path = convert_path(p, PathStyle(windows));
+               lyxerr[Debug::LATEX]
+                       << "<Path correction for LaTeX> ["
+                       << p << "]->>["
+                       << dos_path << ']' << endl;
+               return dos_path;
+       }
+
+       return convert_path(p, PathStyle(posix));
 }
 
 
@@ -141,9 +290,69 @@ char path_separator()
 }
 
 
-void cygwin_path_fix(bool use_cygwin_paths)
+void windows_style_tex_paths(bool use_windows_paths)
+{
+       windows_style_tex_paths_ = use_windows_paths;
+}
+
+
+bool canAutoOpenFile(string const & ext, auto_open_mode const mode)
+{
+       if (ext.empty())
+               return false;
+
+       string const full_ext = "." + ext;
+
+       DWORD bufSize = MAX_PATH + 100;
+       TCHAR buf[MAX_PATH + 100];
+       // reference: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc
+       //                 /platform/shell/reference/shlwapi/registry/assocquerystring.asp
+       char const * action = (mode == VIEW) ? "open" : "edit";
+       return S_OK == AssocQueryString(0, ASSOCSTR_EXECUTABLE,
+               full_ext.c_str(), action, buf, &bufSize);
+}
+
+
+bool autoOpenFile(string const & filename, auto_open_mode const mode)
 {
-       cygwin_path_fix_ = use_cygwin_paths;
+       // reference: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc
+       //                 /platform/shell/reference/functions/shellexecute.asp
+       string const win_path = to_local8bit(from_utf8(convert_path(filename, PathStyle(windows))));
+       char const * action = (mode == VIEW) ? "open" : "edit";
+       return reinterpret_cast<int>(ShellExecute(NULL, action,
+               win_path.c_str(), NULL, NULL, 1)) > 32;
+}
+
+
+void addFontResources()
+{
+#ifdef X_DISPLAY_MISSING
+       // Windows only: Add BaKoMa TrueType font resources
+       string const fonts_dir = addPath(package().system_support(), "fonts");
+       
+       for (int i = 0 ; i < num_fonts_truetype ; ++i) {
+               string const font_current = to_local8bit(from_utf8(convert_path(
+                       addName(fonts_dir, win_fonts_truetype[i] + ".ttf"),
+                       PathStyle(windows))));
+               AddFontResource(font_current.c_str());
+       }
+#endif
+}
+
+
+void restoreFontResources()
+{
+#ifdef X_DISPLAY_MISSING
+       // Windows only: Remove BaKoMa TrueType font resources
+       string const fonts_dir = addPath(package().system_support(), "fonts");
+       
+       for(int i = 0 ; i < num_fonts_truetype ; ++i) {
+               string const font_current = to_local8bit(from_utf8(convert_path(
+                       addName(fonts_dir, win_fonts_truetype[i] + ".ttf"),
+                       PathStyle(windows))));
+               RemoveFontResource(font_current.c_str());
+       }
+#endif
 }
 
 } // namespace os