Merge branch 'master' into jgrpp

# Conflicts:
#	src/os/windows/crashlog_win.cpp
#	src/os/windows/font_win32.cpp
#	src/os/windows/win32.cpp
#	src/os/windows/win32.h
#	src/video/win32_v.cpp
#	src/video/win32_v.h
This commit is contained in:
Jonathan G Rennison
2024-01-12 18:57:14 +00:00
27 changed files with 378 additions and 112 deletions

View File

@@ -5,6 +5,7 @@ add_files(
)
add_files(
library_loader_unix.cpp
unix.cpp
CONDITION UNIX
)

View File

@@ -0,0 +1,64 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD 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 OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file library_loader_unix.cpp Implementation of the LibraryLoader for Linux / MacOS */
#include "../../stdafx.h"
#include <dlfcn.h>
#include "../../library_loader.h"
#include "../../safeguards.h"
/* Emscripten cannot dynamically load other files. */
#if defined(__EMSCRIPTEN__)
void *LibraryLoader::OpenLibrary(const std::string &)
{
this->error = "Dynamic loading is not supported on this platform.";
return nullptr;
}
void LibraryLoader::CloseLibrary()
{
}
void *LibraryLoader::GetSymbol(const std::string &)
{
this->error = "Dynamic loading is not supported on this platform.";
return nullptr;
}
#else
void *LibraryLoader::OpenLibrary(const std::string &filename)
{
void *h = dlopen(filename.c_str(), RTLD_NOW | RTLD_LOCAL);
if (h == nullptr) {
this->error = dlerror();
}
return h;
}
void LibraryLoader::CloseLibrary()
{
dlclose(this->handle);
}
void *LibraryLoader::GetSymbol(const std::string &symbol_name)
{
void *p = dlsym(this->handle, symbol_name.c_str());
if (p == nullptr) {
this->error = dlerror();
}
return p;
}
#endif /* __EMSCRIPTEN__ */

View File

@@ -2,6 +2,7 @@ add_files(
crashlog_win.cpp
font_win32.cpp
font_win32.h
library_loader_win.cpp
string_uniscribe.cpp
string_uniscribe.h
survey_win.cpp

View File

@@ -19,6 +19,7 @@
#include "../../gamelog.h"
#include "../../sl/saveload.h"
#include "../../video/video_driver.hpp"
#include "../../library_loader.h"
#include "../../screenshot.h"
#include "../../debug.h"
#include "../../settings_type.h"
@@ -334,22 +335,7 @@ static const uint MAX_FRAMES = 64;
/* virtual */ char *CrashLogWindows::LogStacktrace(char *buffer, const char *last) const
{
#define M(x) x "\0"
static const char dbg_import[] =
M("dbghelp.dll")
M("SymInitialize")
M("SymSetOptions")
M("SymCleanup")
M("StackWalk64")
M("SymFunctionTableAccess64")
M("SymGetModuleBase64")
M("SymGetModuleInfo64")
M("SymGetSymFromAddr64")
M("SymGetLineFromAddr64")
M("")
;
#undef M
LibraryLoader dbghelp("dbghelp.dll");
struct ProcPtrs {
BOOL (WINAPI * pSymInitialize)(HANDLE, PCSTR, BOOL);
BOOL (WINAPI * pSymSetOptions)(DWORD);
@@ -360,12 +346,22 @@ static const uint MAX_FRAMES = 64;
BOOL (WINAPI * pSymGetModuleInfo64)(HANDLE, DWORD64, PIMAGEHLP_MODULE64);
BOOL (WINAPI * pSymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64);
BOOL (WINAPI * pSymGetLineFromAddr64)(HANDLE, DWORD64, PDWORD, PIMAGEHLP_LINE64);
} proc;
} proc = {
dbghelp.GetFunction("SymInitialize"),
dbghelp.GetFunction("SymSetOptions"),
dbghelp.GetFunction("SymCleanup"),
dbghelp.GetFunction("StackWalk64"),
dbghelp.GetFunction("SymFunctionTableAccess64"),
dbghelp.GetFunction("SymGetModuleBase64"),
dbghelp.GetFunction("SymGetModuleInfo64"),
dbghelp.GetFunction("SymGetSymFromAddr64"),
dbghelp.GetFunction("SymGetLineFromAddr64"),
};
buffer += seprintf(buffer, last, "Decoded stack trace:\n");
/* Try to load the functions from the DLL, if that fails because of a too old dbghelp.dll, just skip it. */
if (LoadLibraryList((Function*)&proc, dbg_import)) {
if (!dbghelp.HasError()) {
/* Initialize symbol handler. */
HANDLE hCur = GetCurrentProcess();
proc.pSymInitialize(hCur, nullptr, TRUE);
@@ -522,12 +518,12 @@ static const uint MAX_FRAMES = 64;
int ret = 0;
HMODULE dbghelp = LoadLibrary(L"dbghelp.dll");
if (dbghelp != nullptr) {
typedef BOOL (WINAPI *MiniDumpWriteDump_t)(HANDLE, DWORD, HANDLE,
typedef BOOL (WINAPI *MiniDumpWriteDumpT)(HANDLE, DWORD, HANDLE,
MINIDUMP_TYPE,
CONST PMINIDUMP_EXCEPTION_INFORMATION,
CONST PMINIDUMP_USER_STREAM_INFORMATION,
CONST PMINIDUMP_CALLBACK_INFORMATION);
MiniDumpWriteDump_t funcMiniDumpWriteDump = GetProcAddressT<MiniDumpWriteDump_t>(dbghelp, "MiniDumpWriteDump");
MiniDumpWriteDumpT funcMiniDumpWriteDump = (MiniDumpWriteDumpT) GetProcAddress(dbghelp, "MiniDumpWriteDump");
if (funcMiniDumpWriteDump != nullptr) {
seprintf(filename, filename_last, "%scrash.dmp", _personal_dir.c_str());
HANDLE file = CreateFile(OTTD2FS(filename).c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, 0);
@@ -751,7 +747,9 @@ static void CDECL CustomAbort(int)
using VEX_HANDLER_TYPE = LONG WINAPI (EXCEPTION_POINTERS *);
void* (WINAPI *AddVectoredExceptionHandler)(ULONG, VEX_HANDLER_TYPE*);
if (LoadLibraryList((Function*)&AddVectoredExceptionHandler, "kernel32.dll\0AddVectoredExceptionHandler\0\0")) {
static LibraryLoader _kernel32("Kernel32.dll");
AddVectoredExceptionHandler = _kernel32.GetFunction("AddVectoredExceptionHandler");
if (AddVectoredExceptionHandler != nullptr) {
AddVectoredExceptionHandler(1, VectoredExceptionHandler);
}
}

View File

@@ -14,9 +14,10 @@
#include "../../core/math_func.hpp"
#include "../../core/mem_func.hpp"
#include "../../fileio_func.h"
#include "../../fontdetection.h"
#include "../../fontcache.h"
#include "../../fontcache/truetypefontcache.h"
#include "../../fontdetection.h"
#include "../../library_loader.h"
#include "../../string_func.h"
#include "../../strings_func.h"
#include "../../zoom_func.h"
@@ -358,8 +359,9 @@ void LoadWin32Font(FontSize fs)
if (AddFontResourceEx(fontPath, FR_PRIVATE, 0) != 0) {
/* Try a nice little undocumented function first for getting the internal font name.
* Some documentation is found at: http://www.undocprint.org/winspool/getfontresourceinfo */
static LibraryLoader _gdi32("gdi32.dll");
typedef BOOL(WINAPI *PFNGETFONTRESOURCEINFO)(LPCTSTR, LPDWORD, LPVOID, DWORD);
static PFNGETFONTRESOURCEINFO GetFontResourceInfo = GetProcAddressT<PFNGETFONTRESOURCEINFO>(GetModuleHandle(L"Gdi32"), "GetFontResourceInfoW");
static PFNGETFONTRESOURCEINFO GetFontResourceInfo = _gdi32.GetFunction("GetFontResourceInfoW");
if (GetFontResourceInfo != nullptr) {
/* Try to query an array of LOGFONTs that describe the file. */

View File

@@ -13,6 +13,8 @@
#include "../../fontcache/truetypefontcache.h"
#include "win32.h"
#include <windows.h>
/** Font cache for fonts that are based on a Win32 font. */
class Win32FontCache : public TrueTypeFontCache {
private:

View File

@@ -0,0 +1,59 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD 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 OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file library_loader_win.cpp Implementation of the LibraryLoader for Windows */
#include "../../stdafx.h"
#include <windows.h>
#include "../../library_loader.h"
#include "../../core/format.hpp"
#include "../../safeguards.h"
static std::string GetLoadError()
{
auto error_code = GetLastError();
char buffer[512];
if (FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, error_code,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buffer, sizeof(buffer), nullptr) == 0) {
return fmt::format("Unknown error {}", error_code);
}
return buffer;
}
void *LibraryLoader::OpenLibrary(const std::string &filename)
{
void *h = ::LoadLibraryW(OTTD2FS(filename).c_str());
if (h == nullptr) {
this->error = GetLoadError();
}
return h;
}
void LibraryLoader::CloseLibrary()
{
HMODULE handle = static_cast<HMODULE>(this->handle);
::FreeLibrary(handle);
}
void *LibraryLoader::GetSymbol(const std::string &symbol_name)
{
HMODULE handle = static_cast<HMODULE>(this->handle);
void *p = reinterpret_cast<void *>(::GetProcAddress(handle, symbol_name.c_str()));
if (p == nullptr) {
this->error = GetLoadError();
}
return p;
}

View File

@@ -418,7 +418,7 @@ static std::vector<SCRIPT_ITEM> UniscribeItemizeString(UniscribeParagraphLayoutF
UniscribeRun run = *i_run;
/* Partial run after line break (either start or end)? Reshape run to get the first/last glyphs right. */
if (i_run == last_run - 1 && remaining_offset < (last_run - 1)->len) {
if (i_run == last_run - 1 && remaining_offset <= (last_run - 1)->len) {
run.len = remaining_offset - 1;
if (!UniscribeShapeRun(this->text_buffer, run)) return nullptr;

View File

@@ -31,12 +31,17 @@
#include <sys/stat.h>
#include "../../language.h"
#include "../../thread.h"
#include "../../library_loader.h"
#include <array>
#include <map>
#include <mutex>
#include "../../safeguards.h"
#if defined(__MINGW32__) && !defined(__MINGW64__) && !(_WIN32_IE >= 0x0500)
#define SHGFP_TYPE_CURRENT 0
#endif /* __MINGW32__ */
static bool _has_console;
static bool _cursor_disable = true;
static bool _cursor_visible = true;
@@ -53,30 +58,6 @@ bool MyShowCursor(bool show, bool toggle)
return !show;
}
/**
* Helper function needed by dynamically loading libraries
*/
bool LoadLibraryList(Function proc[], const char *dll)
{
while (*dll != '\0') {
HMODULE lib;
lib = LoadLibrary(OTTD2FS(dll).c_str());
if (lib == nullptr) return false;
for (;;) {
Function p;
while (*dll++ != '\0') { /* Nothing */ }
if (*dll == '\0') break;
p = GetProcAddressT<Function>(lib, dll);
if (p == nullptr) return false;
*proc++ = p;
}
dll++;
}
return true;
}
void ShowOSErrorBox(const char *buf, bool system)
{
MyShowCursor(true);
@@ -614,7 +595,8 @@ int OTTDStringCompare(std::string_view s1, std::string_view s2)
#endif
if (first_time) {
_CompareStringEx = GetProcAddressT<PFNCOMPARESTRINGEX>(GetModuleHandle(L"Kernel32"), "CompareStringEx");
static LibraryLoader _kernel32("Kernel32.dll");
_CompareStringEx = _kernel32.GetFunction("CompareStringEx");
first_time = false;
}
@@ -657,7 +639,8 @@ int Win32StringContains(const std::string_view str, const std::string_view value
static bool first_time = true;
if (first_time) {
_FindNLSStringEx = GetProcAddressT<PFNFINDNLSSTRINGEX>(GetModuleHandle(L"Kernel32"), "FindNLSStringEx");
static LibraryLoader _kernel32("Kernel32.dll");
_FindNLSStringEx = _kernel32.GetFunction("FindNLSStringEx");
first_time = false;
}
@@ -704,7 +687,8 @@ void PerThreadSetup()
void PerThreadSetupInit()
{
LoadLibraryList((Function*)&_SetThreadStackGuarantee, "kernel32.dll\0SetThreadStackGuarantee\0\0");
static LibraryLoader _kernel32("Kernel32.dll");
_SetThreadStackGuarantee = _kernel32.GetFunction("SetThreadStackGuarantee");
}
bool IsMainThread()

View File

@@ -10,19 +10,11 @@
#ifndef WIN32_H
#define WIN32_H
#include <windows.h>
bool MyShowCursor(bool show, bool toggle = false);
typedef void (*Function)(int);
bool LoadLibraryList(Function proc[], const char *dll);
char *convert_from_fs(const wchar_t *name, char *utf8_buf, size_t buflen);
wchar_t *convert_to_fs(const std::string_view name, wchar_t *utf16_buf, size_t buflen);
#if defined(__MINGW32__) && !defined(__MINGW64__) && !(_WIN32_IE >= 0x0500)
#define SHGFP_TYPE_CURRENT 0
#endif /* __MINGW32__ */
void Win32SetCurrentLocaleName(const char *iso_code);
int OTTDStringCompare(std::string_view s1, std::string_view s2);
int Win32StringContains(const std::string_view str, const std::string_view value, bool case_insensitive);
@@ -33,12 +25,6 @@ int Win32StringContains(const std::string_view str, const std::string_view value
#pragma GCC diagnostic ignored "-Wcast-function-type"
#endif /* __MINGW32__ */
template <typename T>
T GetProcAddressT(HMODULE hModule, LPCSTR lpProcName)
{
return reinterpret_cast<T>(GetProcAddress(hModule, lpProcName));
}
#ifdef __MINGW32__
#pragma GCC diagnostic pop
#endif