mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-22 10:00:33 +00:00
Support for Win98 and earlier.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@10501 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
19e1292d73
commit
73e1a6a470
@ -1,3 +1,14 @@
|
||||
2005-09-30 Angus Leeming <leeming@lyx.org>
|
||||
|
||||
* os_win32.h: new file, providing a public and portable interface
|
||||
to the SHGetFolderPath function for older flavours of Windows.
|
||||
* os_win32.C: tighten up code. Define the ShGetFolder class. Make
|
||||
use of Microsoft's NewAPIs.h if available to provide us with
|
||||
runtime support for Windows 95.
|
||||
(internal_path): always pass the path through GetLongPathName.
|
||||
|
||||
* package.C.in: move lots of stuff out and into os_win32.C.
|
||||
|
||||
2005-09-29 Angus Leeming <leeming@lyx.org>
|
||||
|
||||
* Makefile.am: use the Windows-friendly LYX_ABS_INSTALLED_LOCALEDIR
|
||||
|
@ -4,7 +4,8 @@ SUBDIRS = . tests
|
||||
|
||||
CLEANFILES += $(BUILT_SOURCES)
|
||||
|
||||
EXTRA_DIST = package.C.in pch.h os_cygwin.C os_os2.C os_unix.C os_win32.C
|
||||
EXTRA_DIST = package.C.in pch.h \
|
||||
os_cygwin.C os_os2.C os_unix.C os_win32.C os_win32.h
|
||||
|
||||
noinst_LTLIBRARIES = libsupport.la
|
||||
|
||||
|
@ -14,14 +14,65 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* The GetLongPathNameA function declaration in
|
||||
* <winbase.h> under MinGW or Cygwin is protected
|
||||
* by the WINVER macro which is defined in <windef.h>
|
||||
*
|
||||
* SHGFP_TYPE_CURRENT is defined in <shlobj.h> for __W32API_VERSION >= 3.2
|
||||
* where it is protected by _WIN32_IE.
|
||||
* It is missing in earlier versions of the MinGW w32api headers.
|
||||
*/
|
||||
#if defined(__MINGW32__) || defined(__CYGWIN__) || defined(__CYGWIN32__)
|
||||
# include <w32api.h>
|
||||
# define WINVER 0x0500
|
||||
# define _WIN32_IE 0x0500
|
||||
#endif
|
||||
|
||||
#include "support/os.h"
|
||||
#include "support/os_win32.h"
|
||||
#include "support/lstrings.h"
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
/* 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 <NewAPIs.h>
|
||||
# undef COMPILE_NEWAPIS_STUBS
|
||||
# undef WANT_GETLONGPATHNAME_WRAPPER
|
||||
#endif
|
||||
|
||||
#include <io.h>
|
||||
#include <direct.h> // _getdrive
|
||||
#include <shlobj.h> // SHGetFolderPath
|
||||
|
||||
// Needed by older versions of MinGW.
|
||||
#if defined (__W32API_MAJOR_VERSION) && \
|
||||
defined (__W32API_MINOR_VERSION) && \
|
||||
(__W32API_MAJOR_VERSION < 3 || \
|
||||
__W32API_MAJOR_VERSION == 3 && __W32API_MINOR_VERSION < 2)
|
||||
# define SHGFP_TYPE_CURRENT 0
|
||||
#endif
|
||||
|
||||
using std::endl;
|
||||
using std::string;
|
||||
@ -31,7 +82,7 @@ namespace lyx {
|
||||
namespace support {
|
||||
namespace os {
|
||||
|
||||
void os::init(int /* argc */, char * argv[])
|
||||
void init(int /* argc */, char * argv[])
|
||||
{
|
||||
/* Note from Angus, 17 Jan 2005:
|
||||
*
|
||||
@ -153,13 +204,30 @@ string external_path(string const & p)
|
||||
}
|
||||
|
||||
|
||||
// (Claus H.) Parsing the latex log file in an Win32 environment all
|
||||
// files are mentioned in Win32/DOS syntax. Because LyX uses the dep file
|
||||
// entries to check if any file has been changed we must retranslate
|
||||
// the Win32/DOS pathnames into Cygwin pathnames.
|
||||
namespace {
|
||||
|
||||
string const get_long_path(string const & short_path)
|
||||
{
|
||||
std::vector<char> long_path(PATH_MAX);
|
||||
DWORD result = GetLongPathName(short_path.c_str(),
|
||||
&long_path[0], long_path.size());
|
||||
|
||||
if (result > long_path.size()) {
|
||||
long_path.resize(result);
|
||||
result = GetLongPathName(short_path.c_str(),
|
||||
&long_path[0], long_path.size());
|
||||
BOOST_ASSERT(result <= long_path.size());
|
||||
}
|
||||
|
||||
return (result == 0) ? short_path : &long_path[0];
|
||||
}
|
||||
|
||||
} // namespace anon
|
||||
|
||||
|
||||
string internal_path(string const & p)
|
||||
{
|
||||
return subst(p, "\\", "/");
|
||||
return subst(get_long_path(p), "\\", "/");
|
||||
}
|
||||
|
||||
|
||||
@ -211,6 +279,71 @@ char path_separator()
|
||||
void cygwin_path_fix(bool)
|
||||
{}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
void bail_out()
|
||||
{
|
||||
#ifndef CXX_GLOBAL_CSTD
|
||||
using std::exit;
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
|
||||
} // namespace anon
|
||||
|
||||
|
||||
GetFolderPath::GetFolderPath()
|
||||
: folder_module_(0),
|
||||
folder_path_func_(0)
|
||||
{
|
||||
folder_module_ = LoadLibrary("shfolder.dll");
|
||||
if (!folder_module_) {
|
||||
lyxerr << "Unable to load shfolder.dll\nPlease install."
|
||||
<< std::endl;
|
||||
bail_out();
|
||||
}
|
||||
|
||||
folder_path_func_ = reinterpret_cast<function_pointer>(::GetProcAddress(folder_module_, "SHGetFolderPathA"));
|
||||
if (folder_path_func_ == 0) {
|
||||
lyxerr << "Unable to find SHGetFolderPathA in shfolder.dll\n"
|
||||
"Don't know how to proceed. Sorry."
|
||||
<< std::endl;
|
||||
bail_out();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GetFolderPath::~GetFolderPath()
|
||||
{
|
||||
if (folder_module_)
|
||||
FreeLibrary(folder_module_);
|
||||
}
|
||||
|
||||
|
||||
// Given a folder ID, returns the folder name (in unix-style format).
|
||||
// Eg CSIDL_PERSONAL -> "C:/Documents and Settings/USERNAME/My Documents"
|
||||
string const GetFolderPath::operator()(folder_id _id) const
|
||||
{
|
||||
char folder_path[PATH_MAX];
|
||||
|
||||
int id = 0;
|
||||
switch (_id) {
|
||||
case PERSONAL:
|
||||
id = CSIDL_PERSONAL;
|
||||
break;
|
||||
case APPDATA:
|
||||
id = CSIDL_APPDATA;
|
||||
break;
|
||||
default:
|
||||
BOOST_ASSERT(false);
|
||||
}
|
||||
HRESULT const result = (folder_path_func_)(0, id, 0,
|
||||
SHGFP_TYPE_CURRENT,
|
||||
folder_path);
|
||||
return (result == 0) ? os::internal_path(folder_path) : string();
|
||||
}
|
||||
|
||||
} // namespace os
|
||||
} // namespace support
|
||||
} // namespace lyx
|
||||
|
84
src/support/os_win32.h
Normal file
84
src/support/os_win32.h
Normal file
@ -0,0 +1,84 @@
|
||||
// -*- C++ -*-
|
||||
/**
|
||||
* \file os_win32.h
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author Angus Leeming
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*
|
||||
* These classes should be used only on Windows machines.
|
||||
*/
|
||||
|
||||
#ifndef OS_WIN32_H
|
||||
#define OS_WIN32_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
# error os_win32.h should be compiled only under Windows.
|
||||
#endif
|
||||
|
||||
/* The GetLongPathNameA function declaration in
|
||||
* winbase.h under MinGW or Cygwin is protected
|
||||
* by the WINVER macro which is defined in windef.h
|
||||
*
|
||||
* We need to #include this file to make available the
|
||||
* DWORD, HMODULE et al. typedefs, so check WINVER now.
|
||||
*
|
||||
* Note: __CYGWIN__ can be defined here if building in _WIN32 mode.
|
||||
*/
|
||||
#if defined(__MINGW32__) || defined(__CYGWIN__) || defined(__CYGWIN32__)
|
||||
# if !defined(WINVER) || WINVER < 0x0500
|
||||
# error WINVER must be >= 0x0500
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <windef.h>
|
||||
|
||||
|
||||
namespace lyx {
|
||||
namespace support {
|
||||
namespace os {
|
||||
|
||||
/** Win98 and earlier don't have SHGetFolderPath in shell32.dll.
|
||||
* Microsoft recommend that we load shfolder.dll at run time and
|
||||
* access the function through that.
|
||||
*
|
||||
* shfolder.dll is loaded dynamically in the constructor. If loading
|
||||
* fails or if the .dll is found not to contain SHGetFolderPathA then
|
||||
* the program exits immediately. Otherwise, the .dll is unloaded in
|
||||
* the destructor
|
||||
*
|
||||
* The class makes SHGetFolderPath available through its function operator.
|
||||
* It will work on all versions of Windows >= Win95.
|
||||
*/
|
||||
class GetFolderPath {
|
||||
public:
|
||||
enum folder_id {
|
||||
/// CSIDL_PERSONAL
|
||||
PERSONAL,
|
||||
/// CSIDL_APPDATA
|
||||
APPDATA
|
||||
};
|
||||
|
||||
GetFolderPath();
|
||||
~GetFolderPath();
|
||||
|
||||
/** Wrapper for SHGetFolderPathA, returning
|
||||
* the path asscociated with @c id.
|
||||
*/
|
||||
std::string const operator()(folder_id id) const;
|
||||
private:
|
||||
typedef HRESULT (__stdcall * function_pointer)(HWND, int, HANDLE, DWORD, LPCSTR);
|
||||
|
||||
HMODULE folder_module_;
|
||||
function_pointer folder_path_func_;
|
||||
};
|
||||
|
||||
} // namespace os
|
||||
} // namespace support
|
||||
} // namespace lyx
|
||||
|
||||
#endif // OS_WIN32_H
|
@ -24,7 +24,10 @@
|
||||
#include "support/lstrings.h"
|
||||
#include "support/os.h"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#if defined (USE_WINDOWS_PACKAGING)
|
||||
# include "support/os_win32.h"
|
||||
#endif
|
||||
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
@ -38,32 +41,7 @@
|
||||
#endif
|
||||
|
||||
#if defined (USE_WINDOWS_PACKAGING)
|
||||
|
||||
/*
|
||||
* MinGW's version of winver.h contains this comment:
|
||||
*
|
||||
* If you need Win32 API features newer the Win95 and WinNT then you must
|
||||
* define WINVER before including windows.h or any other method of including
|
||||
* the windef.h header.
|
||||
*
|
||||
* GetLongPathNameA requires WINVER == 0x0500.
|
||||
*
|
||||
* It doesn't matter if the Windows version is older than this because the
|
||||
* function will compile but will fail at run time. See
|
||||
* http://msdn.microsoft.com/library/en-us/mslu/winprog/microsoft_layer_for_unicode_apis_with_limited_support.asp
|
||||
*/
|
||||
# if defined(__MINGW32__)
|
||||
# define WINVER 0x0500
|
||||
# endif
|
||||
|
||||
# include <windows.h>
|
||||
# include <shlobj.h> // SHGetFolderPath
|
||||
|
||||
// Needed for MinGW:
|
||||
# ifndef SHGFP_TYPE_CURRENT
|
||||
# define SHGFP_TYPE_CURRENT 0
|
||||
# endif
|
||||
|
||||
#elif defined (USE_MACOSX_PACKAGING)
|
||||
# include <CoreServices/CoreServices.h> // FSFindFolder, FSRefMakePath
|
||||
#endif
|
||||
@ -234,20 +212,6 @@ string const relative_locale_dir();
|
||||
string const relative_system_support_dir();
|
||||
|
||||
|
||||
#if defined (USE_WINDOWS_PACKAGING)
|
||||
// Given a folder ID, returns the folder name (in unix-style format).
|
||||
// Eg CSIDL_PERSONAL -> "C:/Documents and Settings/USERNAME/My Documents"
|
||||
string const win32_folder_path(int folder_id)
|
||||
{
|
||||
char folder_path[PATH_MAX + 1];
|
||||
if (SUCCEEDED(SHGetFolderPath(0, folder_id, 0,
|
||||
SHGFP_TYPE_CURRENT, folder_path)))
|
||||
return os::internal_path(folder_path);
|
||||
return string();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
std::string const
|
||||
get_build_support_dir(std::string const & binary_dir,
|
||||
exe_build_dir_to_top_build_dir top_build_dir_location)
|
||||
@ -325,7 +289,8 @@ string const get_document_dir(string const & home_dir)
|
||||
{
|
||||
#if defined (USE_WINDOWS_PACKAGING)
|
||||
(void)home_dir; // Silence warning about unused variable.
|
||||
return win32_folder_path(CSIDL_PERSONAL);
|
||||
os::GetFolderPath win32_folder_path;
|
||||
return win32_folder_path(os::GetFolderPath::PERSONAL);
|
||||
#else // Posix-like.
|
||||
return home_dir;
|
||||
#endif
|
||||
@ -379,9 +344,8 @@ string const get_temp_dir()
|
||||
{
|
||||
#if defined (USE_WINDOWS_PACKAGING)
|
||||
// Typical example: C:/TEMP/.
|
||||
char path[PATH_MAX + 1];
|
||||
char path[PATH_MAX];
|
||||
GetTempPath(PATH_MAX, path);
|
||||
GetLongPathName(path, path, PATH_MAX + 1);
|
||||
return os::internal_path(path);
|
||||
#else // Posix-like.
|
||||
return "/tmp";
|
||||
@ -389,8 +353,6 @@ string const get_temp_dir()
|
||||
}
|
||||
|
||||
|
||||
// If we use a 'lazy' lyxerr in the hope of setting the locale before
|
||||
// printing any messages, then we should ensure that it is flushed first.
|
||||
void bail_out()
|
||||
{
|
||||
#ifndef CXX_GLOBAL_CSTD
|
||||
@ -631,7 +593,8 @@ string const get_default_user_support_dir(string const & home_dir)
|
||||
#if defined (USE_WINDOWS_PACKAGING)
|
||||
(void)home_dir; // Silence warning about unused variable.
|
||||
|
||||
return AddPath(win32_folder_path(CSIDL_APPDATA), PACKAGE);
|
||||
os::GetFolderPath win32_folder_path;
|
||||
return AddPath(win32_folder_path(os::GetFolderPath::APPDATA), PACKAGE);
|
||||
|
||||
#elif defined (USE_MACOSX_PACKAGING)
|
||||
(void)home_dir; // Silence warning about unused variable.
|
||||
|
Loading…
Reference in New Issue
Block a user