LCOV - code coverage report
Current view: top level - src - porting.cpp (source / functions) Hit Total Coverage
Test: report Lines: 97 147 66.0 %
Date: 2015-07-11 18:23:49 Functions: 18 27 66.7 %

          Line data    Source code
       1             : /*
       2             : Minetest
       3             : Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
       4             : 
       5             : This program is free software; you can redistribute it and/or modify
       6             : it under the terms of the GNU Lesser General Public License as published by
       7             : the Free Software Foundation; either version 2.1 of the License, or
       8             : (at your option) any later version.
       9             : 
      10             : This program is distributed in the hope that it will be useful,
      11             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             : GNU Lesser General Public License for more details.
      14             : 
      15             : You should have received a copy of the GNU Lesser General Public License along
      16             : with this program; if not, write to the Free Software Foundation, Inc.,
      17             : 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      18             : */
      19             : 
      20             : /*
      21             :         Random portability stuff
      22             : 
      23             :         See comments in porting.h
      24             : */
      25             : 
      26             : #include "porting.h"
      27             : 
      28             : #if defined(__FreeBSD__)
      29             :         #include <sys/types.h>
      30             :         #include <sys/sysctl.h>
      31             : #elif defined(_WIN32)
      32             :         #include <algorithm>
      33             : #endif
      34             : #if !defined(_WIN32)
      35             :         #include <unistd.h>
      36             :         #include <sys/utsname.h>
      37             : #endif
      38             : #if defined(__hpux)
      39             :         #define _PSTAT64
      40             :         #include <sys/pstat.h>
      41             : #endif
      42             : #if !defined(_WIN32) && !defined(__APPLE__) && \
      43             :         !defined(__ANDROID__) && !defined(SERVER)
      44             :         #define XORG_USED
      45             : #endif
      46             : #ifdef XORG_USED
      47             :         #include <X11/Xlib.h>
      48             :         #include <X11/Xutil.h>
      49             : #endif
      50             : 
      51             : #include "config.h"
      52             : #include "debug.h"
      53             : #include "filesys.h"
      54             : #include "log.h"
      55             : #include "util/string.h"
      56             : #include "settings.h"
      57             : #include <list>
      58             : 
      59             : namespace porting
      60             : {
      61             : 
      62             : /*
      63             :         Signal handler (grabs Ctrl-C on POSIX systems)
      64             : */
      65             : 
      66             : bool g_killed = false;
      67             : 
      68           3 : bool * signal_handler_killstatus(void)
      69             : {
      70           3 :         return &g_killed;
      71             : }
      72             : 
      73             : #if !defined(_WIN32) // POSIX
      74             :         #include <signal.h>
      75             : 
      76           0 : void sigint_handler(int sig)
      77             : {
      78           0 :         if(!g_killed) {
      79           0 :                 dstream<<DTIME<<"INFO: sigint_handler(): "
      80           0 :                                 <<"Ctrl-C pressed, shutting down."<<std::endl;
      81             : 
      82             :                 // Comment out for less clutter when testing scripts
      83             :                 /*dstream<<DTIME<<"INFO: sigint_handler(): "
      84             :                                 <<"Printing debug stacks"<<std::endl;
      85             :                 debug_stacks_print();*/
      86             : 
      87           0 :                 g_killed = true;
      88             :         } else {
      89           0 :                 (void)signal(SIGINT, SIG_DFL);
      90             :         }
      91           0 : }
      92             : 
      93           1 : void signal_handler_init(void)
      94             : {
      95           1 :         (void)signal(SIGINT, sigint_handler);
      96           1 : }
      97             : 
      98             : #else // _WIN32
      99             :         #include <signal.h>
     100             : 
     101             : BOOL WINAPI event_handler(DWORD sig)
     102             : {
     103             :         switch (sig) {
     104             :         case CTRL_C_EVENT:
     105             :         case CTRL_CLOSE_EVENT:
     106             :         case CTRL_LOGOFF_EVENT:
     107             :         case CTRL_SHUTDOWN_EVENT:
     108             :                 if (g_killed == false) {
     109             :                         dstream << DTIME << "INFO: event_handler(): "
     110             :                                 << "Ctrl+C, Close Event, Logoff Event or Shutdown Event,"
     111             :                                 " shutting down." << std::endl;
     112             :                         g_killed = true;
     113             :                 } else {
     114             :                         (void)signal(SIGINT, SIG_DFL);
     115             :                 }
     116             :                 break;
     117             :         case CTRL_BREAK_EVENT:
     118             :                 break;
     119             :         }
     120             : 
     121             :         return TRUE;
     122             : }
     123             : 
     124             : void signal_handler_init(void)
     125             : {
     126             :         SetConsoleCtrlHandler((PHANDLER_ROUTINE)event_handler, TRUE);
     127             : }
     128             : 
     129             : #endif
     130             : 
     131             : 
     132             : /*
     133             :         Multithreading support
     134             : */
     135           0 : int getNumberOfProcessors()
     136             : {
     137             : #if defined(_SC_NPROCESSORS_ONLN)
     138             : 
     139           0 :         return sysconf(_SC_NPROCESSORS_ONLN);
     140             : 
     141             : #elif defined(__FreeBSD__) || defined(__APPLE__)
     142             : 
     143             :         unsigned int len, count;
     144             :         len = sizeof(count);
     145             :         return sysctlbyname("hw.ncpu", &count, &len, NULL, 0);
     146             : 
     147             : #elif defined(_GNU_SOURCE)
     148             : 
     149             :         return get_nprocs();
     150             : 
     151             : #elif defined(_WIN32)
     152             : 
     153             :         SYSTEM_INFO sysinfo;
     154             :         GetSystemInfo(&sysinfo);
     155             :         return sysinfo.dwNumberOfProcessors;
     156             : 
     157             : #elif defined(PTW32_VERSION) || defined(__hpux)
     158             : 
     159             :         return pthread_num_processors_np();
     160             : 
     161             : #else
     162             : 
     163             :         return 1;
     164             : 
     165             : #endif
     166             : }
     167             : 
     168             : 
     169             : #ifndef __ANDROID__
     170           0 : bool threadBindToProcessor(threadid_t tid, int pnumber)
     171             : {
     172             : #if defined(_WIN32)
     173             : 
     174             :         HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, 0, tid);
     175             :         if (!hThread)
     176             :                 return false;
     177             : 
     178             :         bool success = SetThreadAffinityMask(hThread, 1 << pnumber) != 0;
     179             : 
     180             :         CloseHandle(hThread);
     181             :         return success;
     182             : 
     183             : #elif (defined(__FreeBSD__) && (__FreeBSD_version >= 702106)) \
     184             :         || defined(__linux) || defined(linux)
     185             : 
     186             :         cpu_set_t cpuset;
     187             : 
     188           0 :         CPU_ZERO(&cpuset);
     189           0 :         CPU_SET(pnumber, &cpuset);
     190           0 :         return pthread_setaffinity_np(tid, sizeof(cpuset), &cpuset) == 0;
     191             : 
     192             : #elif defined(__sun) || defined(sun)
     193             : 
     194             :         return processor_bind(P_LWPID, MAKE_LWPID_PTHREAD(tid),
     195             :                 pnumber, NULL) == 0;
     196             : 
     197             : #elif defined(_AIX)
     198             : 
     199             :         return bindprocessor(BINDTHREAD, (tid_t)tid, pnumber) == 0;
     200             : 
     201             : #elif defined(__hpux) || defined(hpux)
     202             : 
     203             :         pthread_spu_t answer;
     204             : 
     205             :         return pthread_processor_bind_np(PTHREAD_BIND_ADVISORY_NP,
     206             :                 &answer, pnumber, tid) == 0;
     207             : 
     208             : #elif defined(__APPLE__)
     209             : 
     210             :         struct thread_affinity_policy tapol;
     211             : 
     212             :         thread_port_t threadport = pthread_mach_thread_np(tid);
     213             :         tapol.affinity_tag = pnumber + 1;
     214             :         return thread_policy_set(threadport, THREAD_AFFINITY_POLICY,
     215             :                 (thread_policy_t)&tapol, THREAD_AFFINITY_POLICY_COUNT) == KERN_SUCCESS;
     216             : 
     217             : #else
     218             : 
     219             :         return false;
     220             : 
     221             : #endif
     222             : }
     223             : #endif
     224             : 
     225           0 : bool threadSetPriority(threadid_t tid, int prio)
     226             : {
     227             : #if defined(_WIN32)
     228             : 
     229             :         HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, 0, tid);
     230             :         if (!hThread)
     231             :                 return false;
     232             : 
     233             :         bool success = SetThreadPriority(hThread, prio) != 0;
     234             : 
     235             :         CloseHandle(hThread);
     236             :         return success;
     237             : 
     238             : #else
     239             : 
     240             :         struct sched_param sparam;
     241             :         int policy;
     242             : 
     243           0 :         if (pthread_getschedparam(tid, &policy, &sparam) != 0)
     244           0 :                 return false;
     245             : 
     246           0 :         int min = sched_get_priority_min(policy);
     247           0 :         int max = sched_get_priority_max(policy);
     248             : 
     249           0 :         sparam.sched_priority = min + prio * (max - min) / THREAD_PRIORITY_HIGHEST;
     250           0 :         return pthread_setschedparam(tid, policy, &sparam) == 0;
     251             : 
     252             : #endif
     253             : }
     254             : 
     255             : 
     256             : /*
     257             :         Path mangler
     258             : */
     259             : 
     260             : // Default to RUN_IN_PLACE style relative paths
     261           1 : std::string path_share = "..";
     262           1 : std::string path_user = "..";
     263             : 
     264           3 : std::string getDataPath(const char *subpath)
     265             : {
     266           3 :         return path_share + DIR_DELIM + subpath;
     267             : }
     268             : 
     269           1 : void pathRemoveFile(char *path, char delim)
     270             : {
     271             :         // Remove filename and path delimiter
     272             :         int i;
     273           9 :         for(i = strlen(path)-1; i>=0; i--)
     274             :         {
     275           9 :                 if(path[i] == delim)
     276           1 :                         break;
     277             :         }
     278           1 :         path[i] = 0;
     279           1 : }
     280             : 
     281           0 : bool detectMSVCBuildDir(const std::string &path)
     282             : {
     283             :         const char *ends[] = {
     284             :                 "bin\\Release",
     285             :                 "bin\\Debug",
     286             :                 "bin\\Build",
     287             :                 NULL
     288           0 :         };
     289           0 :         return (removeStringEnd(path, ends) != "");
     290             : }
     291             : 
     292           1 : std::string get_sysinfo()
     293             : {
     294             : #ifdef _WIN32
     295             :         OSVERSIONINFO osvi;
     296             :         std::ostringstream oss;
     297             :         std::string tmp;
     298             :         ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
     299             :         osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
     300             :         GetVersionEx(&osvi);
     301             :         tmp = osvi.szCSDVersion;
     302             :         std::replace(tmp.begin(), tmp.end(), ' ', '_');
     303             : 
     304             :         oss << "Windows/" << osvi.dwMajorVersion << "."
     305             :                 << osvi.dwMinorVersion;
     306             :         if (osvi.szCSDVersion[0])
     307             :                 oss << "-" << tmp;
     308             :         oss << " ";
     309             :         #ifdef _WIN64
     310             :         oss << "x86_64";
     311             :         #else
     312             :         BOOL is64 = FALSE;
     313             :         if (IsWow64Process(GetCurrentProcess(), &is64) && is64)
     314             :                 oss << "x86_64"; // 32-bit app on 64-bit OS
     315             :         else
     316             :                 oss << "x86";
     317             :         #endif
     318             : 
     319             :         return oss.str();
     320             : #else
     321             :         struct utsname osinfo;
     322           1 :         uname(&osinfo);
     323           2 :         return std::string(osinfo.sysname) + "/"
     324           2 :                 + osinfo.release + " " + osinfo.machine;
     325             : #endif
     326             : }
     327             : 
     328             : 
     329           0 : bool getCurrentWorkingDir(char *buf, size_t len)
     330             : {
     331             : #ifdef _WIN32
     332             :         DWORD ret = GetCurrentDirectory(len, buf);
     333             :         return (ret != 0) && (ret <= len);
     334             : #else
     335           0 :         return getcwd(buf, len);
     336             : #endif
     337             : }
     338             : 
     339             : 
     340           1 : bool getExecPathFromProcfs(char *buf, size_t buflen)
     341             : {
     342             : #ifndef _WIN32
     343           1 :         buflen--;
     344             : 
     345             :         ssize_t len;
     346           1 :         if ((len = readlink("/proc/self/exe",     buf, buflen)) == -1 &&
     347           1 :                 (len = readlink("/proc/curproc/file", buf, buflen)) == -1 &&
     348             :                 (len = readlink("/proc/curproc/exe",  buf, buflen)) == -1)
     349           0 :                 return false;
     350             : 
     351           1 :         buf[len] = '\0';
     352           1 :         return true;
     353             : #else
     354             :         return false;
     355             : #endif
     356             : }
     357             : 
     358             : //// Windows
     359             : #if defined(_WIN32)
     360             : 
     361             : bool getCurrentExecPath(char *buf, size_t len)
     362             : {
     363             :         DWORD written = GetModuleFileNameA(NULL, buf, len);
     364             :         if (written == 0 || written == len)
     365             :                 return false;
     366             : 
     367             :         return true;
     368             : }
     369             : 
     370             : 
     371             : //// Linux
     372             : #elif defined(linux) || defined(__linux) || defined(__linux__)
     373             : 
     374           1 : bool getCurrentExecPath(char *buf, size_t len)
     375             : {
     376           1 :         if (!getExecPathFromProcfs(buf, len))
     377           0 :                 return false;
     378             : 
     379           1 :         return true;
     380             : }
     381             : 
     382             : 
     383             : //// Mac OS X, Darwin
     384             : #elif defined(__APPLE__)
     385             : 
     386             : bool getCurrentExecPath(char *buf, size_t len)
     387             : {
     388             :         uint32_t lenb = (uint32_t)len;
     389             :         if (_NSGetExecutablePath(buf, &lenb) == -1)
     390             :                 return false;
     391             : 
     392             :         return true;
     393             : }
     394             : 
     395             : 
     396             : //// FreeBSD, NetBSD, DragonFlyBSD
     397             : #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
     398             : 
     399             : bool getCurrentExecPath(char *buf, size_t len)
     400             : {
     401             :         // Try getting path from procfs first, since valgrind
     402             :         // doesn't work with the latter
     403             :         if (getExecPathFromProcfs(buf, len))
     404             :                 return true;
     405             : 
     406             :         int mib[4];
     407             : 
     408             :         mib[0] = CTL_KERN;
     409             :         mib[1] = KERN_PROC;
     410             :         mib[2] = KERN_PROC_PATHNAME;
     411             :         mib[3] = -1;
     412             : 
     413             :         if (sysctl(mib, 4, buf, &len, NULL, 0) == -1)
     414             :                 return false;
     415             : 
     416             :         return true;
     417             : }
     418             : 
     419             : 
     420             : //// Solaris
     421             : #elif defined(__sun) || defined(sun)
     422             : 
     423             : bool getCurrentExecPath(char *buf, size_t len)
     424             : {
     425             :         const char *exec = getexecname();
     426             :         if (exec == NULL)
     427             :                 return false;
     428             : 
     429             :         if (strlcpy(buf, exec, len) >= len)
     430             :                 return false;
     431             : 
     432             :         return true;
     433             : }
     434             : 
     435             : 
     436             : // HP-UX
     437             : #elif defined(__hpux)
     438             : 
     439             : bool getCurrentExecPath(char *buf, size_t len)
     440             : {
     441             :         struct pst_status psts;
     442             : 
     443             :         if (pstat_getproc(&psts, sizeof(psts), 0, getpid()) == -1)
     444             :                 return false;
     445             : 
     446             :         if (pstat_getpathname(buf, len, &psts.pst_fid_text) == -1)
     447             :                 return false;
     448             : 
     449             :         return true;
     450             : }
     451             : 
     452             : 
     453             : #else
     454             : 
     455             : bool getCurrentExecPath(char *buf, size_t len)
     456             : {
     457             :         return false;
     458             : }
     459             : 
     460             : #endif
     461             : 
     462             : 
     463             : //// Windows
     464             : #if defined(_WIN32)
     465             : 
     466             : bool setSystemPaths()
     467             : {
     468             :         char buf[BUFSIZ];
     469             : 
     470             :         // Find path of executable and set path_share relative to it
     471             :         FATAL_ERROR_IF(!getCurrentExecPath(buf, sizeof(buf)),
     472             :                 "Failed to get current executable path");
     473             :         pathRemoveFile(buf, '\\');
     474             : 
     475             :         // Use ".\bin\.."
     476             :         path_share = std::string(buf) + "\\..";
     477             : 
     478             :         // Use "C:\Documents and Settings\user\Application Data\<PROJECT_NAME>"
     479             :         DWORD len = GetEnvironmentVariable("APPDATA", buf, sizeof(buf));
     480             :         FATAL_ERROR_IF(len == 0 || len > sizeof(buf), "Failed to get APPDATA");
     481             : 
     482             :         path_user = std::string(buf) + DIR_DELIM + PROJECT_NAME;
     483             :         return true;
     484             : }
     485             : 
     486             : 
     487             : //// Linux
     488             : #elif defined(linux) || defined(__linux)
     489             : 
     490           1 : bool setSystemPaths()
     491             : {
     492             :         char buf[BUFSIZ];
     493             : 
     494           1 :         if (!getCurrentExecPath(buf, sizeof(buf))) {
     495             : #ifdef __ANDROID__
     496             :                 errorstream << "Unable to read bindir "<< std::endl;
     497             : #else
     498           0 :                 FATAL_ERROR("Unable to read bindir");
     499             : #endif
     500             :                 return false;
     501             :         }
     502             : 
     503           1 :         pathRemoveFile(buf, '/');
     504           2 :         std::string bindir(buf);
     505             : 
     506             :         // Find share directory from these.
     507             :         // It is identified by containing the subdirectory "builtin".
     508           2 :         std::list<std::string> trylist;
     509           2 :         std::string static_sharedir = STATIC_SHAREDIR;
     510           1 :         if (static_sharedir != "" && static_sharedir != ".")
     511           1 :                 trylist.push_back(static_sharedir);
     512             : 
     513           2 :         trylist.push_back(bindir + DIR_DELIM ".." DIR_DELIM "share"
     514           1 :                 DIR_DELIM + PROJECT_NAME);
     515           1 :         trylist.push_back(bindir + DIR_DELIM "..");
     516             : 
     517             : #ifdef __ANDROID__
     518             :         trylist.push_back(path_user);
     519             : #endif
     520             : 
     521           8 :         for (std::list<std::string>::const_iterator
     522           4 :                         i = trylist.begin(); i != trylist.end(); i++) {
     523           3 :                 const std::string &trypath = *i;
     524          10 :                 if (!fs::PathExists(trypath) ||
     525           6 :                         !fs::PathExists(trypath + DIR_DELIM + "builtin")) {
     526           2 :                         dstream << "WARNING: system-wide share not found at \""
     527           2 :                                         << trypath << "\""<< std::endl;
     528           2 :                         continue;
     529             :                 }
     530             : 
     531             :                 // Warn if was not the first alternative
     532           1 :                 if (i != trylist.begin()) {
     533           1 :                         dstream << "WARNING: system-wide share found at \""
     534           1 :                                         << trypath << "\"" << std::endl;
     535             :                 }
     536             : 
     537           1 :                 path_share = trypath;
     538           1 :                 break;
     539             :         }
     540             : 
     541             : #ifndef __ANDROID__
     542           2 :         path_user = std::string(getenv("HOME")) + DIR_DELIM "."
     543           1 :                 + PROJECT_NAME;
     544             : #endif
     545             : 
     546           1 :         return true;
     547             : }
     548             : 
     549             : 
     550             : //// Mac OS X
     551             : #elif defined(__APPLE__)
     552             : 
     553             : bool setSystemPaths()
     554             : {
     555             :         CFBundleRef main_bundle = CFBundleGetMainBundle();
     556             :         CFURLRef resources_url = CFBundleCopyResourcesDirectoryURL(main_bundle);
     557             :         char path[PATH_MAX];
     558             :         if (CFURLGetFileSystemRepresentation(resources_url,
     559             :                         TRUE, (UInt8 *)path, PATH_MAX)) {
     560             :                 path_share = std::string(path);
     561             :         } else {
     562             :                 dstream << "WARNING: Could not determine bundle resource path" << std::endl;
     563             :         }
     564             :         CFRelease(resources_url);
     565             : 
     566             :         path_user = std::string(getenv("HOME"))
     567             :                 + "/Library/Application Support/"
     568             :                 + PROJECT_NAME;
     569             :         return true;
     570             : }
     571             : 
     572             : 
     573             : #else
     574             : 
     575             : bool setSystemPaths()
     576             : {
     577             :         path_share = STATIC_SHAREDIR;
     578             :         path_user  = std::string(getenv("HOME")) + DIR_DELIM "."
     579             :                 + lowercase(PROJECT_NAME);
     580             :         return true;
     581             : }
     582             : 
     583             : 
     584             : #endif
     585             : 
     586             : 
     587           1 : void initializePaths()
     588             : {
     589             : #if RUN_IN_PLACE
     590             :         char buf[BUFSIZ];
     591             : 
     592             :         infostream << "Using relative paths (RUN_IN_PLACE)" << std::endl;
     593             : 
     594             :         bool success =
     595             :                 getCurrentExecPath(buf, sizeof(buf)) ||
     596             :                 getExecPathFromProcfs(buf, sizeof(buf));
     597             : 
     598             :         if (success) {
     599             :                 pathRemoveFile(buf, DIR_DELIM_CHAR);
     600             :                 std::string execpath(buf);
     601             : 
     602             :                 path_share = execpath + DIR_DELIM "..";
     603             :                 path_user  = execpath + DIR_DELIM "..";
     604             : 
     605             :                 if (detectMSVCBuildDir(execpath)) {
     606             :                         path_share += DIR_DELIM "..";
     607             :                         path_user  += DIR_DELIM "..";
     608             :                 }
     609             :         } else {
     610             :                 errorstream << "Failed to get paths by executable location, "
     611             :                         "trying cwd" << std::endl;
     612             : 
     613             :                 if (!getCurrentWorkingDir(buf, sizeof(buf)))
     614             :                         FATAL_ERROR("Ran out of methods to get paths");
     615             : 
     616             :                 size_t cwdlen = strlen(buf);
     617             :                 if (cwdlen >= 1 && buf[cwdlen - 1] == DIR_DELIM_CHAR) {
     618             :                         cwdlen--;
     619             :                         buf[cwdlen] = '\0';
     620             :                 }
     621             : 
     622             :                 if (cwdlen >= 4 && !strcmp(buf + cwdlen - 4, DIR_DELIM "bin"))
     623             :                         pathRemoveFile(buf, DIR_DELIM_CHAR);
     624             : 
     625             :                 std::string execpath(buf);
     626             : 
     627             :                 path_share = execpath;
     628             :                 path_user  = execpath;
     629             :         }
     630             : 
     631             : #else
     632           1 :         infostream << "Using system-wide paths (NOT RUN_IN_PLACE)" << std::endl;
     633             : 
     634           1 :         if (!setSystemPaths())
     635           0 :                 errorstream << "Failed to get one or more system-wide path" << std::endl;
     636             : 
     637             : #endif
     638             : 
     639           1 :         infostream << "Detected share path: " << path_share << std::endl;
     640           1 :         infostream << "Detected user path: " << path_user << std::endl;
     641           1 : }
     642             : 
     643             : 
     644             : 
     645           1 : void setXorgClassHint(const video::SExposedVideoData &video_data,
     646             :         const std::string &name)
     647             : {
     648             : #ifdef XORG_USED
     649           1 :         if (video_data.OpenGLLinux.X11Display == NULL)
     650           0 :                 return;
     651             : 
     652           1 :         XClassHint *classhint = XAllocClassHint();
     653           1 :         classhint->res_name  = (char *)name.c_str();
     654           1 :         classhint->res_class = (char *)name.c_str();
     655             : 
     656           1 :         XSetClassHint((Display *)video_data.OpenGLLinux.X11Display,
     657           2 :                 video_data.OpenGLLinux.X11Window, classhint);
     658           1 :         XFree(classhint);
     659             : #endif
     660             : }
     661             : 
     662             : 
     663             : ////
     664             : //// Video/Display Information (Client-only)
     665             : ////
     666             : 
     667             : #ifndef SERVER
     668             : 
     669             : static irr::IrrlichtDevice *device;
     670             : 
     671           1 : void initIrrlicht(irr::IrrlichtDevice *device_)
     672             : {
     673           1 :         device = device_;
     674           1 : }
     675             : 
     676        8238 : v2u32 getWindowSize()
     677             : {
     678        8238 :         return device->getVideoDriver()->getScreenSize();
     679             : }
     680             : 
     681             : 
     682           0 : std::vector<core::vector3d<u32> > getSupportedVideoModes()
     683             : {
     684           0 :         IrrlichtDevice *nulldevice = createDevice(video::EDT_NULL);
     685           0 :         sanity_check(nulldevice != NULL);
     686             : 
     687           0 :         std::vector<core::vector3d<u32> > mlist;
     688           0 :         video::IVideoModeList *modelist = nulldevice->getVideoModeList();
     689             : 
     690           0 :         u32 num_modes = modelist->getVideoModeCount();
     691           0 :         for (u32 i = 0; i != num_modes; i++) {
     692           0 :                 core::dimension2d<u32> mode_res = modelist->getVideoModeResolution(i);
     693           0 :                 s32 mode_depth = modelist->getVideoModeDepth(i);
     694           0 :                 mlist.push_back(core::vector3d<u32>(mode_res.Width, mode_res.Height, mode_depth));
     695             :         }
     696             : 
     697           0 :         nulldevice->drop();
     698             : 
     699           0 :         return mlist;
     700             : }
     701             : 
     702           1 : std::vector<irr::video::E_DRIVER_TYPE> getSupportedVideoDrivers()
     703             : {
     704           1 :         std::vector<irr::video::E_DRIVER_TYPE> drivers;
     705             : 
     706           7 :         for (int i = 0; i != irr::video::EDT_COUNT; i++) {
     707           6 :                 if (irr::IrrlichtDevice::isDriverSupported((irr::video::E_DRIVER_TYPE)i))
     708           4 :                         drivers.push_back((irr::video::E_DRIVER_TYPE)i);
     709             :         }
     710             : 
     711           1 :         return drivers;
     712             : }
     713             : 
     714           4 : const char *getVideoDriverName(irr::video::E_DRIVER_TYPE type)
     715             : {
     716             :         static const char *driver_ids[] = {
     717             :                 "null",
     718             :                 "software",
     719             :                 "burningsvideo",
     720             :                 "direct3d8",
     721             :                 "direct3d9",
     722             :                 "opengl",
     723             :                 "ogles1",
     724             :                 "ogles2",
     725             :         };
     726             : 
     727           4 :         return driver_ids[type];
     728             : }
     729             : 
     730             : 
     731           0 : const char *getVideoDriverFriendlyName(irr::video::E_DRIVER_TYPE type)
     732             : {
     733             :         static const char *driver_names[] = {
     734             :                 "NULL Driver",
     735             :                 "Software Renderer",
     736             :                 "Burning's Video",
     737             :                 "Direct3D 8",
     738             :                 "Direct3D 9",
     739             :                 "OpenGL",
     740             :                 "OpenGL ES1",
     741             :                 "OpenGL ES2",
     742             :         };
     743             : 
     744           0 :         return driver_names[type];
     745             : }
     746             : 
     747             : #       ifndef __ANDROID__
     748             : #               ifdef XORG_USED
     749             : 
     750           1 : static float calcDisplayDensity()
     751             : {
     752           1 :         const char* current_display = getenv("DISPLAY");
     753             : 
     754           1 :         if (current_display != NULL) {
     755           1 :                         Display * x11display = XOpenDisplay(current_display);
     756             : 
     757           1 :                         if (x11display != NULL) {
     758             :                                 /* try x direct */
     759             :                                 float dpi_height =
     760           2 :                                                 floor(DisplayHeight(x11display, 0) /
     761           2 :                                                                 (DisplayHeightMM(x11display, 0) * 0.039370) + 0.5);
     762             :                                 float dpi_width =
     763           2 :                                                 floor(DisplayWidth(x11display, 0) /
     764           2 :                                                                 (DisplayWidthMM(x11display, 0) * 0.039370) +0.5);
     765             : 
     766           1 :                                 XCloseDisplay(x11display);
     767             : 
     768           1 :                                 return std::max(dpi_height,dpi_width) / 96.0;
     769             :                         }
     770             :                 }
     771             : 
     772             :         /* return manually specified dpi */
     773           0 :         return g_settings->getFloat("screen_dpi")/96.0;
     774             : }
     775             : 
     776             : 
     777        1252 : float getDisplayDensity()
     778             : {
     779        1252 :         static float cached_display_density = calcDisplayDensity();
     780        1252 :         return cached_display_density;
     781             : }
     782             : 
     783             : 
     784             : #               else // XORG_USED
     785             : float getDisplayDensity()
     786             : {
     787             :         return g_settings->getFloat("screen_dpi")/96.0;
     788             : }
     789             : #               endif // XORG_USED
     790             : 
     791           0 : v2u32 getDisplaySize()
     792             : {
     793           0 :         IrrlichtDevice *nulldevice = createDevice(video::EDT_NULL);
     794             : 
     795           0 :         core::dimension2d<u32> deskres = nulldevice->getVideoModeList()->getDesktopResolution();
     796           0 :         nulldevice -> drop();
     797             : 
     798           0 :         return deskres;
     799             : }
     800             : #       endif // __ANDROID__
     801             : #endif // SERVER
     802             : 
     803           3 : } //namespace porting
     804             : 

Generated by: LCOV version 1.11