mirror of
https://codeberg.org/comaps/comaps
synced 2026-01-06 04:24:29 +00:00
Organic Maps sources as of 02.04.2025 (fad26bbf22ac3da75e01e62aa01e5c8e11861005)
To expand with full Organic Maps and Maps.ME commits history run: git remote add om-historic [om-historic.git repo url] git fetch --tags om-historic git replace squashed-history historic-commits
This commit is contained in:
203
platform/platform_mac.mm
Normal file
203
platform/platform_mac.mm
Normal file
@@ -0,0 +1,203 @@
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
#include "base/file_name_utils.hpp"
|
||||
#include "base/logging.hpp"
|
||||
|
||||
#include "std/target_os.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include <Foundation/NSAutoreleasePool.h>
|
||||
#include <Foundation/NSBundle.h>
|
||||
#include <Foundation/NSFileManager.h>
|
||||
#include <Foundation/NSPathUtilities.h>
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <dispatch/dispatch.h>
|
||||
|
||||
#import <SystemConfiguration/SystemConfiguration.h>
|
||||
#import <netinet/in.h>
|
||||
|
||||
|
||||
Platform::Platform()
|
||||
{
|
||||
// OMaps.app/Content/Resources or omim-build-debug for tests.
|
||||
std::string const resourcesPath = NSBundle.mainBundle.resourcePath.UTF8String;
|
||||
// Omaps.app or omim-build-debug for tests.
|
||||
std::string const bundlePath = NSBundle.mainBundle.bundlePath.UTF8String;
|
||||
// Current working directory, can be overrided for Xcode projects in the scheme's settings.
|
||||
std::string const currentDir = [NSFileManager.defaultManager currentDirectoryPath].UTF8String;
|
||||
|
||||
char const * envResourcesDir = ::getenv("MWM_RESOURCES_DIR");
|
||||
char const * envWritableDir = ::getenv("MWM_WRITABLE_DIR");
|
||||
|
||||
if (envResourcesDir && envWritableDir)
|
||||
{
|
||||
m_resourcesDir = envResourcesDir;
|
||||
m_writableDir = envWritableDir;
|
||||
}
|
||||
else if (resourcesPath == bundlePath)
|
||||
{
|
||||
// we're the console app, probably unit test, and path is our directory
|
||||
m_resourcesDir = bundlePath + "/../../data/";
|
||||
if (!IsFileExistsByFullPath(m_resourcesDir))
|
||||
{
|
||||
// Check development environment without symlink but with git repo
|
||||
std::string const repoPath = bundlePath + "/../../../omim/data/";
|
||||
if (IsFileExistsByFullPath(repoPath))
|
||||
m_resourcesDir = repoPath;
|
||||
else
|
||||
m_resourcesDir = "./data/";
|
||||
}
|
||||
m_writableDir = m_resourcesDir;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_resourcesDir = resourcesPath + "/";
|
||||
std::string const paths[] =
|
||||
{
|
||||
// Developers can set a symlink to the data folder.
|
||||
m_resourcesDir + "../../../data/",
|
||||
// Check development environment without a symlink but with a git repo.
|
||||
m_resourcesDir + "../../../../omim/data/",
|
||||
m_resourcesDir + "../../../../organicmaps/data/",
|
||||
// Working directory is set to the data folder or any project's subfolder.
|
||||
currentDir + "/../data",
|
||||
// Working directory is set to the project's root.
|
||||
currentDir + "/data",
|
||||
// Working directory is set to the build folder with binaries.
|
||||
currentDir + "/../omim/data",
|
||||
currentDir + "/../organicmaps/data",
|
||||
};
|
||||
// Find the writable path.
|
||||
for (auto const & path : paths)
|
||||
{
|
||||
if (IsFileExistsByFullPath(path))
|
||||
{
|
||||
m_writableDir = path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Xcode-launched Mac projects are built into a non-standard folder and may need
|
||||
// a customized working directory.
|
||||
if (m_writableDir.empty())
|
||||
{
|
||||
for (char const * keyword : {"/omim/", "/organicmaps/"})
|
||||
{
|
||||
if (auto const p = currentDir.rfind(keyword); p != std::string::npos)
|
||||
{
|
||||
m_writableDir = m_resourcesDir = currentDir.substr(0, p) + keyword + "data/";
|
||||
break;
|
||||
}
|
||||
if (auto const p = m_resourcesDir.rfind(keyword); p != std::string::npos)
|
||||
{
|
||||
m_writableDir = m_resourcesDir.substr(0, p) + keyword + "data/";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_writableDir.empty())
|
||||
{
|
||||
NSArray * dirPaths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
|
||||
NSString * supportDir = [dirPaths objectAtIndex:0];
|
||||
m_writableDir = supportDir.UTF8String;
|
||||
#ifdef BUILD_DESIGNER
|
||||
m_writableDir += "/OMapsData.Designer/";
|
||||
#else // BUILD_DESIGNER
|
||||
m_writableDir += "/OMapsData/";
|
||||
#endif // BUILD_DESIGNER
|
||||
::mkdir(m_writableDir.c_str(), 0755);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_resourcesDir.empty())
|
||||
m_resourcesDir = ".";
|
||||
m_resourcesDir = base::AddSlashIfNeeded(m_resourcesDir);
|
||||
m_writableDir = base::AddSlashIfNeeded(m_writableDir);
|
||||
|
||||
m_settingsDir = m_writableDir;
|
||||
|
||||
NSString * tempDir = NSTemporaryDirectory();
|
||||
if (tempDir == nil)
|
||||
tempDir = @"/tmp";
|
||||
m_tmpDir = tempDir.UTF8String;
|
||||
base::AddSlashIfNeeded(m_tmpDir);
|
||||
|
||||
m_guiThread = std::make_unique<platform::GuiThread>();
|
||||
|
||||
LOG(LDEBUG, ("Resources Directory:", m_resourcesDir));
|
||||
LOG(LDEBUG, ("Writable Directory:", m_writableDir));
|
||||
LOG(LDEBUG, ("Tmp Directory:", m_tmpDir));
|
||||
LOG(LDEBUG, ("Settings Directory:", m_settingsDir));
|
||||
}
|
||||
|
||||
std::string Platform::DeviceName() const
|
||||
{
|
||||
return OMIM_OS_NAME;
|
||||
}
|
||||
|
||||
std::string Platform::DeviceModel() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
Platform::EConnectionType Platform::ConnectionStatus()
|
||||
{
|
||||
struct sockaddr_in zero;
|
||||
memset(&zero, 0, sizeof(zero));
|
||||
zero.sin_len = sizeof(zero);
|
||||
zero.sin_family = AF_INET;
|
||||
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, reinterpret_cast<const struct sockaddr*>(&zero));
|
||||
if (!reachability)
|
||||
return EConnectionType::CONNECTION_NONE;
|
||||
SCNetworkReachabilityFlags flags;
|
||||
bool const gotFlags = SCNetworkReachabilityGetFlags(reachability, &flags);
|
||||
CFRelease(reachability);
|
||||
if (!gotFlags || ((flags & kSCNetworkReachabilityFlagsReachable) == 0))
|
||||
return EConnectionType::CONNECTION_NONE;
|
||||
SCNetworkReachabilityFlags userActionRequired = kSCNetworkReachabilityFlagsConnectionRequired | kSCNetworkReachabilityFlagsInterventionRequired;
|
||||
if ((flags & userActionRequired) == userActionRequired)
|
||||
return EConnectionType::CONNECTION_NONE;
|
||||
return EConnectionType::CONNECTION_WIFI;
|
||||
}
|
||||
|
||||
// static
|
||||
Platform::ChargingStatus Platform::GetChargingStatus()
|
||||
{
|
||||
return Platform::ChargingStatus::Plugged;
|
||||
}
|
||||
|
||||
uint8_t Platform::GetBatteryLevel()
|
||||
{
|
||||
// This value is always 100 for desktop.
|
||||
return 100;
|
||||
}
|
||||
|
||||
void Platform::GetSystemFontNames(FilesList & res) const
|
||||
{
|
||||
}
|
||||
|
||||
// static
|
||||
time_t Platform::GetFileCreationTime(std::string const & path)
|
||||
{
|
||||
struct stat st;
|
||||
if (0 == stat(path.c_str(), &st))
|
||||
return st.st_birthtimespec.tv_sec;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// static
|
||||
time_t Platform::GetFileModificationTime(std::string const & path)
|
||||
{
|
||||
struct stat st;
|
||||
if (0 == stat(path.c_str(), &st))
|
||||
return st.st_mtimespec.tv_sec;
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user