#include "porting.h"
-#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)
#include <sys/types.h>
#include <sys/sysctl.h>
+ extern char **environ;
#elif defined(_WIN32)
#include <windows.h>
#include <wincrypt.h>
#include <algorithm>
#include <shlwapi.h>
+ #include <shellapi.h>
+ #include <mmsystem.h>
#endif
#if !defined(_WIN32)
#include <unistd.h>
#include <sys/utsname.h>
+ #if !defined(__ANDROID__)
+ #include <spawn.h>
+ #endif
#endif
#if defined(__hpux)
#define _PSTAT64
#include <sys/pstat.h>
#endif
+#if defined(__ANDROID__)
+ #include "porting_android.h"
+#endif
+#if defined(__APPLE__)
+ // For _NSGetEnviron()
+ // Related: https://gitlab.haskell.org/ghc/ghc/issues/2458
+ #include <crt_externs.h>
+#endif
+
+#if defined(__HAIKU__)
+ #include <FindDirectory.h>
+#endif
#include "config.h"
#include "debug.h"
#include "filesys.h"
#include "log.h"
#include "util/string.h"
-#include "settings.h"
#include <list>
#include <cstdarg>
#include <cstdio>
+#if !defined(SERVER) && defined(_WIN32)
+// On Windows export some driver-specific variables to encourage Minetest to be
+// executed on the discrete GPU in case of systems with two. Portability is fun.
+extern "C" {
+ __declspec(dllexport) DWORD NvOptimusEnablement = 1;
+ __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 1;
+}
+#endif
+
namespace porting
{
return true;
}
+#elif defined(__HAIKU__)
+
+bool getCurrentExecPath(char *buf, size_t len)
+{
+ return find_path(B_APP_IMAGE_SYMBOL, B_FIND_PATH_IMAGE_PATH, NULL, buf, len) == B_OK;
+}
//// Solaris
#elif defined(__sun) || defined(sun)
return c;
}
+static bool open_uri(const std::string &uri)
+{
+ if (uri.find_first_of("\r\n") != std::string::npos) {
+ errorstream << "Unable to open URI as it is invalid, contains new line: " << uri << std::endl;
+ return false;
+ }
+
+#if defined(_WIN32)
+ return (intptr_t)ShellExecuteA(NULL, NULL, uri.c_str(), NULL, NULL, SW_SHOWNORMAL) > 32;
+#elif defined(__ANDROID__)
+ openURIAndroid(uri);
+ return true;
+#elif defined(__APPLE__)
+ const char *argv[] = {"open", uri.c_str(), NULL};
+ return posix_spawnp(NULL, "open", NULL, NULL, (char**)argv,
+ (*_NSGetEnviron())) == 0;
+#else
+ const char *argv[] = {"xdg-open", uri.c_str(), NULL};
+ return posix_spawnp(NULL, "xdg-open", NULL, NULL, (char**)argv, environ) == 0;
+#endif
+}
+
+bool open_url(const std::string &url)
+{
+ if (url.substr(0, 7) != "http://" && url.substr(0, 8) != "https://") {
+ errorstream << "Unable to open browser as URL is missing schema: " << url << std::endl;
+ return false;
+ }
+
+ return open_uri(url);
+}
+
+bool open_directory(const std::string &path)
+{
+ if (!fs::IsDir(path)) {
+ errorstream << "Unable to open directory as it does not exist: " << path << std::endl;
+ return false;
+ }
+
+ return open_uri(path);
+}
+
// Load performance counter frequency only once at startup
#ifdef _WIN32
inline double get_perf_freq()
{
+ // Also use this opportunity to enable high-res timers
+ timeBeginPeriod(1);
+
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
return freq.QuadPart;