Merge branch 'master' into jgrpp
# Conflicts: # src/debug.cpp # src/lang/russian.txt # src/misc_gui.cpp # src/os/windows/crashlog_win.cpp # src/os/windows/font_win32.cpp # src/os/windows/win32.cpp # src/rail_cmd.cpp # src/window_gui.h
This commit is contained in:
@@ -231,7 +231,7 @@ static char *PrintModuleInfo(char *output, const char *last, HMODULE mod)
|
||||
GetModuleFileName(mod, buffer, MAX_PATH);
|
||||
GetFileInfo(&dfi, buffer);
|
||||
output += seprintf(output, last, " %-20s handle: %p size: %d crc: %.8X date: %d-%.2d-%.2d %.2d:%.2d:%.2d\n",
|
||||
FS2OTTD(buffer),
|
||||
FS2OTTD(buffer).c_str(),
|
||||
mod,
|
||||
dfi.size,
|
||||
dfi.crc32,
|
||||
@@ -579,7 +579,7 @@ char *CrashLogWindows::AppendDecodedStacktrace(char *buffer, const char *last) c
|
||||
MiniDumpWriteDump_t funcMiniDumpWriteDump = (MiniDumpWriteDump_t)GetProcAddress(dbghelp, "MiniDumpWriteDump");
|
||||
if (funcMiniDumpWriteDump != nullptr) {
|
||||
seprintf(filename, filename_last, "%scrash.dmp", _personal_dir.c_str());
|
||||
HANDLE file = CreateFile(OTTD2FS(filename), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, 0);
|
||||
HANDLE file = CreateFile(OTTD2FS(filename).c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, 0);
|
||||
HANDLE proc = GetCurrentProcess();
|
||||
DWORD procid = GetCurrentProcessId();
|
||||
MINIDUMP_EXCEPTION_INFORMATION mdei;
|
||||
@@ -810,7 +810,8 @@ static INT_PTR CALLBACK CrashDialogFunc(HWND wnd, UINT msg, WPARAM wParam, LPARA
|
||||
switch (msg) {
|
||||
case WM_INITDIALOG: {
|
||||
/* We need to put the crash-log in a separate buffer because the default
|
||||
* buffer in OTTD2FS is not large enough (512 chars) */
|
||||
* buffer in MB_TO_WIDE is not large enough (512 chars) */
|
||||
wchar_t filenamebuf[MAX_PATH * 2];
|
||||
wchar_t crash_msgW[lengthof(CrashLogWindows::current->crashlog)];
|
||||
/* Convert unix -> dos newlines because the edit box only supports that properly :( */
|
||||
const char *unix_nl = CrashLogWindows::current->crashlog;
|
||||
@@ -825,19 +826,23 @@ static INT_PTR CALLBACK CrashDialogFunc(HWND wnd, UINT msg, WPARAM wParam, LPARA
|
||||
|
||||
/* Add path to crash.log and crash.dmp (if any) to the crash window text */
|
||||
size_t len = wcslen(_crash_desc) + 2;
|
||||
len += wcslen(OTTD2FS(CrashLogWindows::current->crashlog_filename)) + 2;
|
||||
len += wcslen(OTTD2FS(CrashLogWindows::current->crashdump_filename)) + 2;
|
||||
len += wcslen(OTTD2FS(CrashLogWindows::current->screenshot_filename)) + 1;
|
||||
len += wcslen(convert_to_fs(CrashLogWindows::current->crashlog_filename, filenamebuf, lengthof(filenamebuf))) + 2;
|
||||
len += wcslen(convert_to_fs(CrashLogWindows::current->crashdump_filename, filenamebuf, lengthof(filenamebuf))) + 2;
|
||||
len += wcslen(convert_to_fs(CrashLogWindows::current->screenshot_filename, filenamebuf, lengthof(filenamebuf))) + 1;
|
||||
|
||||
wchar_t *text = AllocaM(wchar_t, len);
|
||||
_snwprintf(text, len, _crash_desc, OTTD2FS(CrashLogWindows::current->crashlog_filename));
|
||||
if (_settings_client.gui.developer > 0 && OTTD2FS(CrashLogWindows::current->crashdump_filename)[0] != L'\0') {
|
||||
wcscat(text, L"\n");
|
||||
wcscat(text, OTTD2FS(CrashLogWindows::current->crashdump_filename));
|
||||
int printed = _snwprintf(text, len, _crash_desc, convert_to_fs(CrashLogWindows::current->crashlog_filename, filenamebuf, lengthof(filenamebuf)));
|
||||
if (printed < 0 || (size_t)printed > len) {
|
||||
MessageBox(wnd, L"Catastrophic failure trying to display crash message. Could not perform text formatting.", L"OpenTTD", MB_ICONERROR);
|
||||
return FALSE;
|
||||
}
|
||||
if (OTTD2FS(CrashLogWindows::current->screenshot_filename)[0] != L'\0') {
|
||||
if (_settings_client.gui.developer > 0 && convert_to_fs(CrashLogWindows::current->crashdump_filename, filenamebuf, lengthof(filenamebuf))[0] != L'\0') {
|
||||
wcscat(text, L"\n");
|
||||
wcscat(text, OTTD2FS(CrashLogWindows::current->screenshot_filename));
|
||||
wcscat(text, filenamebuf);
|
||||
}
|
||||
if (convert_to_fs(CrashLogWindows::current->screenshot_filename, filenamebuf, lengthof(filenamebuf))[0] != L'\0') {
|
||||
wcscat(text, L"\n");
|
||||
wcscat(text, filenamebuf);
|
||||
}
|
||||
|
||||
SetDlgItemText(wnd, 10, text);
|
||||
@@ -853,11 +858,13 @@ static INT_PTR CALLBACK CrashDialogFunc(HWND wnd, UINT msg, WPARAM wParam, LPARA
|
||||
case 13: // Emergency save
|
||||
_savegame_DBGL_data = CrashLogWindows::current->crashlog;
|
||||
_save_DBGC_data = true;
|
||||
wchar_t filenamebuf[MAX_PATH * 2];
|
||||
char filename[MAX_PATH];
|
||||
if (CrashLogWindows::current->WriteSavegame(filename, lastof(filename), CrashLogWindows::current->name_buffer)) {
|
||||
size_t len = wcslen(_save_succeeded) + wcslen(OTTD2FS(filename)) + 1;
|
||||
convert_to_fs(filename, filenamebuf, lengthof(filenamebuf));
|
||||
size_t len = lengthof(_save_succeeded) + wcslen(filenamebuf) + 1;
|
||||
wchar_t *text = AllocaM(wchar_t, len);
|
||||
_snwprintf(text, len, _save_succeeded, OTTD2FS(filename));
|
||||
_snwprintf(text, len, _save_succeeded, filenamebuf);
|
||||
MessageBox(wnd, text, L"Save successful", MB_ICONINFORMATION);
|
||||
} else {
|
||||
MessageBox(wnd, L"Save failed", L"Save failed", MB_ICONINFORMATION);
|
||||
@@ -866,7 +873,7 @@ static INT_PTR CALLBACK CrashDialogFunc(HWND wnd, UINT msg, WPARAM wParam, LPARA
|
||||
_save_DBGC_data = false;
|
||||
break;
|
||||
case 15: // Expand window to show crash-message
|
||||
_expanded ^= 1;
|
||||
_expanded = !_expanded;
|
||||
SetWndSize(wnd, _expanded);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
|
||||
}
|
||||
|
||||
/* Convert font name to file system encoding. */
|
||||
wchar_t *font_namep = wcsdup(OTTD2FS(font_name));
|
||||
wchar_t *font_namep = wcsdup(OTTD2FS(font_name).c_str());
|
||||
|
||||
for (index = 0;; index++) {
|
||||
wchar_t *s;
|
||||
@@ -377,6 +377,7 @@ Win32FontCache::Win32FontCache(FontSize fs, const LOGFONT &logfont, int pixels)
|
||||
{
|
||||
this->dc = CreateCompatibleDC(nullptr);
|
||||
this->SetFontSize(fs, pixels);
|
||||
this->fontname = FS2OTTD(this->logfont.lfFaceName);
|
||||
}
|
||||
|
||||
Win32FontCache::~Win32FontCache()
|
||||
@@ -440,7 +441,7 @@ void Win32FontCache::SetFontSize(FontSize fs, int pixels)
|
||||
|
||||
font_height_cache[this->fs] = this->GetHeight();
|
||||
|
||||
DEBUG(freetype, 2, "Loaded font '%s' with size %d", FS2OTTD((LPTSTR)((BYTE *)otm + (ptrdiff_t)otm->otmpFullName)), pixels);
|
||||
DEBUG(freetype, 2, "Loaded font '%s' with size %d", FS2OTTD((LPWSTR)((BYTE *)otm + (ptrdiff_t)otm->otmpFullName)).c_str(), pixels);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -499,7 +500,7 @@ void Win32FontCache::ClearFontCache()
|
||||
* For anti-aliased rendering, GDI uses the strange value range of 0 to 64,
|
||||
* inclusively. To map this to 0 to 255, we shift left by two and then
|
||||
* subtract one. */
|
||||
uint pitch = Align(aa ? gm.gmBlackBoxX : std::max(gm.gmBlackBoxX / 8u, 1u), 4);
|
||||
uint pitch = Align(aa ? gm.gmBlackBoxX : std::max((gm.gmBlackBoxX + 7u) / 8u, 1u), 4);
|
||||
|
||||
/* Draw shadow for medium size. */
|
||||
if (this->fs == FS_NORMAL && !aa) {
|
||||
@@ -543,10 +544,10 @@ void Win32FontCache::ClearFontCache()
|
||||
/* Convert characters outside of the BMP into surrogate pairs. */
|
||||
WCHAR chars[2];
|
||||
if (key >= 0x010000U) {
|
||||
chars[0] = (WCHAR)(((key - 0x010000U) >> 10) + 0xD800);
|
||||
chars[1] = (WCHAR)(((key - 0x010000U) & 0x3FF) + 0xDC00);
|
||||
chars[0] = (wchar_t)(((key - 0x010000U) >> 10) + 0xD800);
|
||||
chars[1] = (wchar_t)(((key - 0x010000U) & 0x3FF) + 0xDC00);
|
||||
} else {
|
||||
chars[0] = (WCHAR)(key & 0xFFFF);
|
||||
chars[0] = (wchar_t)(key & 0xFFFF);
|
||||
}
|
||||
|
||||
WORD glyphs[2] = { 0, 0 };
|
||||
@@ -607,12 +608,12 @@ void LoadWin32Font(FontSize fs)
|
||||
|
||||
/* See if this is an absolute path. */
|
||||
if (FileExists(settings->font)) {
|
||||
convert_to_fs(settings->font, fontPath, lengthof(fontPath), false);
|
||||
convert_to_fs(settings->font, fontPath, lengthof(fontPath));
|
||||
} else {
|
||||
/* Scan the search-paths to see if it can be found. */
|
||||
std::string full_font = FioFindFullPath(BASE_DIR, settings->font);
|
||||
if (!full_font.empty()) {
|
||||
convert_to_fs(full_font.c_str(), fontPath, lengthof(fontPath), false);
|
||||
convert_to_fs(full_font.c_str(), fontPath, lengthof(fontPath));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -650,7 +651,7 @@ void LoadWin32Font(FontSize fs)
|
||||
|
||||
if (logfont.lfFaceName[0] == 0) {
|
||||
logfont.lfWeight = strcasestr(settings->font, " bold") != nullptr ? FW_BOLD : FW_NORMAL; // Poor man's way to allow selecting bold fonts.
|
||||
convert_to_fs(settings->font, logfont.lfFaceName, lengthof(logfont.lfFaceName), false);
|
||||
convert_to_fs(settings->font, logfont.lfFaceName, lengthof(logfont.lfFaceName));
|
||||
}
|
||||
|
||||
HFONT font = CreateFontIndirect(&logfont);
|
||||
|
||||
@@ -21,6 +21,7 @@ private:
|
||||
HDC dc = nullptr; ///< Cached GDI device context.
|
||||
HGDIOBJ old_font; ///< Old font selected into the GDI context.
|
||||
SIZE glyph_size; ///< Maximum size of regular glyphs.
|
||||
std::string fontname; ///< Cached copy of this->logfont.lfFaceName
|
||||
|
||||
void SetFontSize(FontSize fs, int pixels);
|
||||
|
||||
@@ -33,7 +34,7 @@ public:
|
||||
~Win32FontCache();
|
||||
void ClearFontCache() override;
|
||||
GlyphID MapCharToGlyph(WChar key) override;
|
||||
const char *GetFontName() override { return FS2OTTD(this->logfont.lfFaceName); }
|
||||
const char *GetFontName() override { return this->fontname.c_str(); }
|
||||
const void *GetOSHandle() override { return &this->logfont; }
|
||||
};
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ bool LoadLibraryList(Function proc[], const char *dll)
|
||||
{
|
||||
while (*dll != '\0') {
|
||||
HMODULE lib;
|
||||
lib = LoadLibrary(OTTD2FS(dll));
|
||||
lib = LoadLibrary(OTTD2FS(dll).c_str());
|
||||
|
||||
if (lib == nullptr) return false;
|
||||
for (;;) {
|
||||
@@ -83,12 +83,12 @@ bool LoadLibraryList(Function proc[], const char *dll)
|
||||
void ShowOSErrorBox(const char *buf, bool system)
|
||||
{
|
||||
MyShowCursor(true);
|
||||
MessageBox(GetActiveWindow(), OTTD2FS(buf), L"Error!", MB_ICONSTOP | MB_TASKMODAL);
|
||||
MessageBox(GetActiveWindow(), OTTD2FS(buf).c_str(), L"Error!", MB_ICONSTOP | MB_TASKMODAL);
|
||||
}
|
||||
|
||||
void OSOpenBrowser(const char *url)
|
||||
{
|
||||
ShellExecute(GetActiveWindow(), L"open", OTTD2FS(url), nullptr, nullptr, SW_SHOWNORMAL);
|
||||
ShellExecute(GetActiveWindow(), L"open", OTTD2FS(url).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
|
||||
}
|
||||
|
||||
/* Code below for windows version of opendir/readdir/closedir copied and
|
||||
@@ -147,14 +147,14 @@ DIR *opendir(const wchar_t *path)
|
||||
if ((fa != INVALID_FILE_ATTRIBUTES) && (fa & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
d = dir_calloc();
|
||||
if (d != nullptr) {
|
||||
wchar_t search_path[MAX_PATH];
|
||||
std::wstring search_path = path;
|
||||
bool slash = path[wcslen(path) - 1] == '\\';
|
||||
|
||||
/* build search path for FindFirstFile, try not to append additional slashes
|
||||
* as it throws Win9x off its groove for root directories */
|
||||
_snwprintf(search_path, lengthof(search_path), L"%s%s*", path, slash ? L"" : L"\\");
|
||||
*lastof(search_path) = '\0';
|
||||
d->hFind = FindFirstFile(search_path, &d->fd);
|
||||
if (!slash) search_path += L"\\";
|
||||
search_path += L"*";
|
||||
d->hFind = FindFirstFile(search_path.c_str(), &d->fd);
|
||||
|
||||
if (d->hFind != INVALID_HANDLE_VALUE ||
|
||||
GetLastError() == ERROR_NO_MORE_FILES) { // the directory is empty
|
||||
@@ -252,7 +252,7 @@ bool FiosGetDiskFreeSpace(const char *path, uint64 *tot)
|
||||
UINT sem = SetErrorMode(SEM_FAILCRITICALERRORS); // disable 'no-disk' message box
|
||||
|
||||
ULARGE_INTEGER bytes_free;
|
||||
bool retval = GetDiskFreeSpaceEx(OTTD2FS(path), &bytes_free, nullptr, nullptr);
|
||||
bool retval = GetDiskFreeSpaceEx(OTTD2FS(path).c_str(), &bytes_free, nullptr, nullptr);
|
||||
if (retval) *tot = bytes_free.QuadPart;
|
||||
|
||||
SetErrorMode(sem); // reset previous setting
|
||||
@@ -422,7 +422,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
|
||||
/* Convert the command line to UTF-8. We need a dedicated buffer
|
||||
* for this because argv[] points into this buffer and this needs to
|
||||
* be available between subsequent calls to FS2OTTD(). */
|
||||
char *cmdline = stredup(FS2OTTD(GetCommandLine()));
|
||||
char *cmdline = stredup(FS2OTTD(GetCommandLine()).c_str());
|
||||
|
||||
#if defined(_DEBUG)
|
||||
CreateConsole();
|
||||
@@ -560,34 +560,40 @@ bool GetClipboardContents(char *buffer, const char *last)
|
||||
|
||||
|
||||
/**
|
||||
* Convert to OpenTTD's encoding from wide characters.
|
||||
* Convert to OpenTTD's encoding from a wide string.
|
||||
* OpenTTD internal encoding is UTF8.
|
||||
* The returned value's contents can only be guaranteed until the next call to
|
||||
* this function. So if the value is needed for anything else, use convert_from_fs
|
||||
* @param name pointer to a valid string that will be converted (local, or wide)
|
||||
* @return pointer to the converted string; if failed string is of zero-length
|
||||
* @param name valid string that will be converted (local, or wide)
|
||||
* @return converted string; if failed string is of zero-length
|
||||
* @see the current code-page comes from video\win32_v.cpp, event-notification
|
||||
* WM_INPUTLANGCHANGE
|
||||
*/
|
||||
const char *FS2OTTD(const wchar_t *name)
|
||||
std::string FS2OTTD(const std::wstring &name)
|
||||
{
|
||||
static char utf8_buf[512];
|
||||
return convert_from_fs(name, utf8_buf, lengthof(utf8_buf));
|
||||
int name_len = (name.length() >= INT_MAX) ? INT_MAX : (int)name.length();
|
||||
int len = WideCharToMultiByte(CP_UTF8, 0, name.c_str(), name_len, nullptr, 0, nullptr, nullptr);
|
||||
if (len <= 0) return std::string();
|
||||
char *utf8_buf = AllocaM(char, len + 1);
|
||||
utf8_buf[len] = '\0';
|
||||
WideCharToMultiByte(CP_UTF8, 0, name.c_str(), name_len, utf8_buf, len, nullptr, nullptr);
|
||||
return std::string(utf8_buf, static_cast<size_t>(len));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert from OpenTTD's encoding to wide characters.
|
||||
* Convert from OpenTTD's encoding to a wide string.
|
||||
* OpenTTD internal encoding is UTF8.
|
||||
* The returned value's contents can only be guaranteed until the next call to
|
||||
* this function. So if the value is needed for anything else, use convert_from_fs
|
||||
* @param name pointer to a valid string that will be converted (UTF8)
|
||||
* @param name valid string that will be converted (UTF8)
|
||||
* @param console_cp convert to the console encoding instead of the normal system encoding.
|
||||
* @return pointer to the converted string; if failed string is of zero-length
|
||||
* @return converted string; if failed string is of zero-length
|
||||
*/
|
||||
const wchar_t *OTTD2FS(const char *name, bool console_cp)
|
||||
std::wstring OTTD2FS(const std::string &name)
|
||||
{
|
||||
static TCHAR system_buf[512];
|
||||
return convert_to_fs(name, system_buf, lengthof(system_buf), console_cp);
|
||||
int name_len = (name.length() >= INT_MAX) ? INT_MAX : (int)name.length();
|
||||
int len = MultiByteToWideChar(CP_UTF8, 0, name.c_str(), name_len, nullptr, 0);
|
||||
if (len <= 0) return std::wstring();
|
||||
wchar_t *system_buf = AllocaM(wchar_t, len + 1);
|
||||
system_buf[len] = L'\0';
|
||||
MultiByteToWideChar(CP_UTF8, 0, name.c_str(), name_len, system_buf, len);
|
||||
return std::wstring(system_buf, static_cast<size_t>(len));
|
||||
}
|
||||
|
||||
|
||||
@@ -601,10 +607,8 @@ const wchar_t *OTTD2FS(const char *name, bool console_cp)
|
||||
*/
|
||||
char *convert_from_fs(const wchar_t *name, char *utf8_buf, size_t buflen)
|
||||
{
|
||||
const wchar_t *wide_buf = name;
|
||||
|
||||
/* Convert UTF-16 string to UTF-8. */
|
||||
int len = WideCharToMultiByte(CP_UTF8, 0, wide_buf, -1, utf8_buf, (int)buflen, nullptr, nullptr);
|
||||
int len = WideCharToMultiByte(CP_UTF8, 0, name, -1, utf8_buf, (int)buflen, nullptr, nullptr);
|
||||
if (len == 0) utf8_buf[0] = '\0';
|
||||
|
||||
return utf8_buf;
|
||||
@@ -621,7 +625,7 @@ char *convert_from_fs(const wchar_t *name, char *utf8_buf, size_t buflen)
|
||||
* @param console_cp convert to the console encoding instead of the normal system encoding.
|
||||
* @return pointer to system_buf. If conversion fails the string is of zero-length
|
||||
*/
|
||||
wchar_t *convert_to_fs(const char *name, wchar_t *system_buf, size_t buflen, bool console_cp)
|
||||
wchar_t *convert_to_fs(const char *name, wchar_t *system_buf, size_t buflen)
|
||||
{
|
||||
int len = MultiByteToWideChar(CP_UTF8, 0, name, -1, system_buf, (int)buflen);
|
||||
if (len == 0) system_buf[0] = '\0';
|
||||
@@ -632,9 +636,12 @@ wchar_t *convert_to_fs(const char *name, wchar_t *system_buf, size_t buflen, boo
|
||||
/** Determine the current user's locale. */
|
||||
const char *GetCurrentLocale(const char *)
|
||||
{
|
||||
const LANGID userUiLang = GetUserDefaultUILanguage();
|
||||
const LCID userUiLocale = MAKELCID(userUiLang, SORT_DEFAULT);
|
||||
|
||||
char lang[9], country[9];
|
||||
if (GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, lang, lengthof(lang)) == 0 ||
|
||||
GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, country, lengthof(country)) == 0) {
|
||||
if (GetLocaleInfoA(userUiLocale, LOCALE_SISO639LANGNAME, lang, lengthof(lang)) == 0 ||
|
||||
GetLocaleInfoA(userUiLocale, LOCALE_SISO3166CTRYNAME, country, lengthof(country)) == 0) {
|
||||
/* Unable to retrieve the locale. */
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ 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 char *name, wchar_t *utf16_buf, size_t buflen, bool console_cp = false);
|
||||
wchar_t *convert_to_fs(const char *name, wchar_t *utf16_buf, size_t buflen);
|
||||
|
||||
#if defined(__MINGW32__) && !defined(__MINGW64__) && !(_WIN32_IE >= 0x0500)
|
||||
#define SHGFP_TYPE_CURRENT 0
|
||||
|
||||
Reference in New Issue
Block a user