Merge branch 'master' into jgrpp
# Conflicts: # cmake/CompileFlags.cmake # src/crashlog.cpp # src/fileio.cpp # src/fileio_func.h # src/fios_gui.cpp # src/ini_load.cpp # src/ini_type.h # src/lang/english.txt # src/lang/german.txt # src/lang/korean.txt # src/network/network_client.cpp # src/order_base.h # src/order_cmd.cpp # src/os/windows/win32.cpp # src/road_cmd.cpp # src/saveload/saveload.cpp # src/saveload/saveload.h # src/settings.cpp # src/station_cmd.cpp # src/stdafx.h # src/table/settings.ini # src/tree_cmd.cpp # src/tree_gui.cpp # src/vehicle_base.h # src/video/cocoa/cocoa_v.mm # src/video/cocoa/event.mm # src/video/cocoa/wnd_quartz.mm # src/viewport.cpp # src/widgets/tree_widget.h
This commit is contained in:
@@ -12,7 +12,9 @@
|
||||
#include "../../rev.h"
|
||||
#include "macos.h"
|
||||
#include "../../string_func.h"
|
||||
#include "../../fileio_func.h"
|
||||
#include <pthread.h>
|
||||
#include <array>
|
||||
|
||||
#define Rect OTTDRect
|
||||
#define Point OTTDPoint
|
||||
@@ -40,6 +42,10 @@ typedef struct {
|
||||
#define NSOperatingSystemVersion OTTDOperatingSystemVersion
|
||||
#endif
|
||||
|
||||
#ifdef WITH_COCOA
|
||||
static NSAutoreleasePool *_ottd_autorelease_pool;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get the version of the MacOS we are running under. Code adopted
|
||||
* from http://www.cocoadev.com/index.pl?DeterminingOSVersion
|
||||
@@ -66,6 +72,10 @@ void GetMacOSVersion(int *return_major, int *return_minor, int *return_bugfix)
|
||||
}
|
||||
|
||||
#if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_10)
|
||||
#ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
SInt32 systemVersion, version_major, version_minor, version_bugfix;
|
||||
if (Gestalt(gestaltSystemVersion, &systemVersion) == noErr) {
|
||||
if (systemVersion >= 0x1040) {
|
||||
@@ -78,6 +88,9 @@ void GetMacOSVersion(int *return_major, int *return_minor, int *return_bugfix)
|
||||
*return_bugfix = (int)GB(systemVersion, 0, 4);
|
||||
}
|
||||
}
|
||||
#ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -191,6 +204,45 @@ bool GetClipboardContents(char *buffer, const char *last)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Set the application's bundle directory.
|
||||
*
|
||||
* This is needed since OS X application bundles do not have a
|
||||
* current directory and the data files are 'somewhere' in the bundle.
|
||||
*/
|
||||
void CocoaSetApplicationBundleDir()
|
||||
{
|
||||
extern std::array<std::string, NUM_SEARCHPATHS> _searchpaths;
|
||||
|
||||
char tmp[MAXPATHLEN];
|
||||
CFAutoRelease<CFURLRef> url(CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle()));
|
||||
if (CFURLGetFileSystemRepresentation(url.get(), true, (unsigned char *)tmp, MAXPATHLEN)) {
|
||||
_searchpaths[SP_APPLICATION_BUNDLE_DIR] = tmp;
|
||||
AppendPathSeparator(_searchpaths[SP_APPLICATION_BUNDLE_DIR]);
|
||||
} else {
|
||||
_searchpaths[SP_APPLICATION_BUNDLE_DIR].clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup autorelease for the application pool.
|
||||
*
|
||||
* These are called from main() to prevent a _NSAutoreleaseNoPool error when
|
||||
* exiting before the cocoa video driver has been loaded
|
||||
*/
|
||||
void CocoaSetupAutoreleasePool()
|
||||
{
|
||||
_ottd_autorelease_pool = [ [ NSAutoreleasePool alloc ] init ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Autorelease the application pool.
|
||||
*/
|
||||
void CocoaReleaseAutoreleasePool()
|
||||
{
|
||||
[ _ottd_autorelease_pool release ];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -290,6 +290,17 @@ void MacOSResetScriptCache(FontSize size)
|
||||
_font_cache[size].reset();
|
||||
}
|
||||
|
||||
/** Register an external font file with the CoreText system. */
|
||||
void MacOSRegisterExternalFont(const char *file_path)
|
||||
{
|
||||
if (!MacOSVersionIsAtLeast(10, 6, 0)) return;
|
||||
|
||||
CFAutoRelease<CFStringRef> path(CFStringCreateWithCString(kCFAllocatorDefault, file_path, kCFStringEncodingUTF8));
|
||||
CFAutoRelease<CFURLRef> url(CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path.get(), kCFURLPOSIXPathStyle, false));
|
||||
|
||||
CTFontManagerRegisterFontsForURL(url.get(), kCTFontManagerScopeProcess, nullptr);
|
||||
}
|
||||
|
||||
/** Store current language locale as a CoreFounation locale. */
|
||||
void MacOSSetCurrentLocaleName(const char *iso_code)
|
||||
{
|
||||
|
||||
@@ -85,4 +85,6 @@ void MacOSResetScriptCache(FontSize size);
|
||||
void MacOSSetCurrentLocaleName(const char *iso_code);
|
||||
int MacOSStringCompare(const char *s1, const char *s2);
|
||||
|
||||
void MacOSRegisterExternalFont(const char *file_path);
|
||||
|
||||
#endif /* STRING_OSX_H */
|
||||
|
||||
@@ -235,8 +235,8 @@ void ShowOSErrorBox(const char *buf, bool system)
|
||||
#endif
|
||||
|
||||
#ifdef WITH_COCOA
|
||||
void cocoaSetupAutoreleasePool();
|
||||
void cocoaReleaseAutoreleasePool();
|
||||
void CocoaSetupAutoreleasePool();
|
||||
void CocoaReleaseAutoreleasePool();
|
||||
#endif
|
||||
|
||||
int CDECL main(int argc, char *argv[])
|
||||
@@ -245,7 +245,7 @@ int CDECL main(int argc, char *argv[])
|
||||
for (int i = 0; i < argc; i++) ValidateString(argv[i]);
|
||||
|
||||
#ifdef WITH_COCOA
|
||||
cocoaSetupAutoreleasePool();
|
||||
CocoaSetupAutoreleasePool();
|
||||
/* This is passed if we are launched by double-clicking */
|
||||
if (argc >= 2 && strncmp(argv[1], "-psn", 4) == 0) {
|
||||
argv[1] = nullptr;
|
||||
@@ -261,7 +261,7 @@ int CDECL main(int argc, char *argv[])
|
||||
int ret = openttd_main(argc, argv);
|
||||
|
||||
#ifdef WITH_COCOA
|
||||
cocoaReleaseAutoreleasePool();
|
||||
CocoaReleaseAutoreleasePool();
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -576,7 +576,7 @@ char *CrashLogWindows::AppendDecodedStacktrace(char *buffer, const char *last) c
|
||||
CONST PMINIDUMP_CALLBACK_INFORMATION);
|
||||
MiniDumpWriteDump_t funcMiniDumpWriteDump = (MiniDumpWriteDump_t)GetProcAddress(dbghelp, "MiniDumpWriteDump");
|
||||
if (funcMiniDumpWriteDump != nullptr) {
|
||||
seprintf(filename, filename_last, "%scrash.dmp", _personal_dir);
|
||||
seprintf(filename, filename_last, "%scrash.dmp", _personal_dir.c_str());
|
||||
HANDLE file = CreateFile(OTTD2FS(filename), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, 0);
|
||||
HANDLE proc = GetCurrentProcess();
|
||||
DWORD procid = GetCurrentProcessId();
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include "../../language.h"
|
||||
#include "../../thread.h"
|
||||
#include <array>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#if defined(__MINGW32__)
|
||||
@@ -477,76 +478,84 @@ char *getcwd(char *buf, size_t size)
|
||||
return buf;
|
||||
}
|
||||
|
||||
extern char *_config_file;
|
||||
extern std::string _config_file;
|
||||
|
||||
void DetermineBasePaths(const char *exe)
|
||||
{
|
||||
char tmp[MAX_PATH];
|
||||
extern std::array<std::string, NUM_SEARCHPATHS> _searchpaths;
|
||||
|
||||
TCHAR path[MAX_PATH];
|
||||
#ifdef WITH_PERSONAL_DIR
|
||||
if (SUCCEEDED(OTTDSHGetFolderPath(nullptr, CSIDL_PERSONAL, nullptr, SHGFP_TYPE_CURRENT, path))) {
|
||||
strecpy(tmp, FS2OTTD(path), lastof(tmp));
|
||||
AppendPathSeparator(tmp, lastof(tmp));
|
||||
strecat(tmp, PERSONAL_DIR, lastof(tmp));
|
||||
AppendPathSeparator(tmp, lastof(tmp));
|
||||
_searchpaths[SP_PERSONAL_DIR] = stredup(tmp);
|
||||
std::string tmp(FS2OTTD(path));
|
||||
AppendPathSeparator(tmp);
|
||||
tmp += PERSONAL_DIR;
|
||||
AppendPathSeparator(tmp);
|
||||
_searchpaths[SP_PERSONAL_DIR] = tmp;
|
||||
|
||||
tmp += "content_download";
|
||||
AppendPathSeparator(tmp);
|
||||
_searchpaths[SP_AUTODOWNLOAD_PERSONAL_DIR] = tmp;
|
||||
} else {
|
||||
_searchpaths[SP_PERSONAL_DIR] = nullptr;
|
||||
_searchpaths[SP_PERSONAL_DIR].clear();
|
||||
}
|
||||
|
||||
if (SUCCEEDED(OTTDSHGetFolderPath(nullptr, CSIDL_COMMON_DOCUMENTS, nullptr, SHGFP_TYPE_CURRENT, path))) {
|
||||
strecpy(tmp, FS2OTTD(path), lastof(tmp));
|
||||
AppendPathSeparator(tmp, lastof(tmp));
|
||||
strecat(tmp, PERSONAL_DIR, lastof(tmp));
|
||||
AppendPathSeparator(tmp, lastof(tmp));
|
||||
_searchpaths[SP_SHARED_DIR] = stredup(tmp);
|
||||
std::string tmp(FS2OTTD(path));
|
||||
AppendPathSeparator(tmp);
|
||||
tmp += PERSONAL_DIR;
|
||||
AppendPathSeparator(tmp);
|
||||
_searchpaths[SP_SHARED_DIR] = tmp;
|
||||
} else {
|
||||
_searchpaths[SP_SHARED_DIR] = nullptr;
|
||||
_searchpaths[SP_SHARED_DIR].clear();
|
||||
}
|
||||
#else
|
||||
_searchpaths[SP_PERSONAL_DIR] = nullptr;
|
||||
_searchpaths[SP_SHARED_DIR] = nullptr;
|
||||
_searchpaths[SP_PERSONAL_DIR].clear();
|
||||
_searchpaths[SP_SHARED_DIR].clear();
|
||||
#endif
|
||||
|
||||
if (_config_file == nullptr) {
|
||||
/* Get the path to working directory of OpenTTD. */
|
||||
getcwd(tmp, lengthof(tmp));
|
||||
AppendPathSeparator(tmp, lastof(tmp));
|
||||
_searchpaths[SP_WORKING_DIR] = stredup(tmp);
|
||||
if (_config_file.empty()) {
|
||||
char cwd[MAX_PATH];
|
||||
getcwd(cwd, lengthof(cwd));
|
||||
std::string cwd_s(cwd);
|
||||
AppendPathSeparator(cwd_s);
|
||||
_searchpaths[SP_WORKING_DIR] = cwd_s;
|
||||
} else {
|
||||
/* Use the folder of the config file as working directory. */
|
||||
TCHAR config_dir[MAX_PATH];
|
||||
_tcsncpy(path, convert_to_fs(_config_file, path, lengthof(path)), lengthof(path));
|
||||
_tcsncpy(path, convert_to_fs(_config_file.c_str(), path, lengthof(path)), lengthof(path));
|
||||
if (!GetFullPathName(path, lengthof(config_dir), config_dir, nullptr)) {
|
||||
DEBUG(misc, 0, "GetFullPathName failed (%lu)\n", GetLastError());
|
||||
_searchpaths[SP_WORKING_DIR] = nullptr;
|
||||
_searchpaths[SP_WORKING_DIR].clear();
|
||||
} else {
|
||||
strecpy(tmp, convert_from_fs(config_dir, tmp, lengthof(tmp)), lastof(tmp));
|
||||
char *s = strrchr(tmp, PATHSEPCHAR);
|
||||
*(s + 1) = '\0';
|
||||
_searchpaths[SP_WORKING_DIR] = stredup(tmp);
|
||||
std::string tmp(FS2OTTD(config_dir));
|
||||
auto pos = tmp.find_last_of(PATHSEPCHAR);
|
||||
if (pos != std::string::npos) tmp.erase(pos + 1);
|
||||
|
||||
_searchpaths[SP_WORKING_DIR] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
if (!GetModuleFileName(nullptr, path, lengthof(path))) {
|
||||
DEBUG(misc, 0, "GetModuleFileName failed (%lu)\n", GetLastError());
|
||||
_searchpaths[SP_BINARY_DIR] = nullptr;
|
||||
_searchpaths[SP_BINARY_DIR].clear();
|
||||
} else {
|
||||
TCHAR exec_dir[MAX_PATH];
|
||||
_tcsncpy(path, convert_to_fs(exe, path, lengthof(path)), lengthof(path));
|
||||
if (!GetFullPathName(path, lengthof(exec_dir), exec_dir, nullptr)) {
|
||||
DEBUG(misc, 0, "GetFullPathName failed (%lu)\n", GetLastError());
|
||||
_searchpaths[SP_BINARY_DIR] = nullptr;
|
||||
_searchpaths[SP_BINARY_DIR].clear();
|
||||
} else {
|
||||
strecpy(tmp, convert_from_fs(exec_dir, tmp, lengthof(tmp)), lastof(tmp));
|
||||
char *s = strrchr(tmp, PATHSEPCHAR);
|
||||
*(s + 1) = '\0';
|
||||
_searchpaths[SP_BINARY_DIR] = stredup(tmp);
|
||||
std::string tmp(FS2OTTD(exec_dir));
|
||||
auto pos = tmp.find_last_of(PATHSEPCHAR);
|
||||
if (pos != std::string::npos) tmp.erase(pos + 1);
|
||||
|
||||
_searchpaths[SP_BINARY_DIR] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
_searchpaths[SP_INSTALLATION_DIR] = nullptr;
|
||||
_searchpaths[SP_APPLICATION_BUNDLE_DIR] = nullptr;
|
||||
_searchpaths[SP_INSTALLATION_DIR].clear();
|
||||
_searchpaths[SP_APPLICATION_BUNDLE_DIR].clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user