Cpp11 initializers: last src root changeset (#6022)
[oweals/minetest.git] / src / porting.cpp
index 7ded58b3fe14788a44a534a0c8ea0063c64dd254..0cc323934ba18b2f56afdb8ad4e4e47a66f33c1c 100644 (file)
@@ -25,7 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "porting.h"
 
-#if defined(__FreeBSD__)
+#if defined(__FreeBSD__)  || defined(__NetBSD__) || defined(__DragonFly__)
        #include <sys/types.h>
        #include <sys/sysctl.h>
 #elif defined(_WIN32)
@@ -258,7 +258,7 @@ bool getCurrentExecPath(char *buf, size_t len)
 
 
 //// Linux
-#elif defined(linux) || defined(__linux) || defined(__linux__)
+#elif defined(__linux__)
 
 bool getCurrentExecPath(char *buf, size_t len)
 {
@@ -374,7 +374,7 @@ bool setSystemPaths()
 
 
 //// Linux
-#elif defined(linux) || defined(__linux)
+#elif defined(__linux__)
 
 bool setSystemPaths()
 {
@@ -408,7 +408,7 @@ bool setSystemPaths()
 #endif
 
        for (std::list<std::string>::const_iterator
-                       i = trylist.begin(); i != trylist.end(); i++) {
+                       i = trylist.begin(); i != trylist.end(); ++i) {
                const std::string &trypath = *i;
                if (!fs::PathExists(trypath) ||
                        !fs::PathExists(trypath + DIR_DELIM + "builtin")) {
@@ -611,6 +611,145 @@ void setXorgClassHint(const video::SExposedVideoData &video_data,
 #endif
 }
 
+bool setWindowIcon(IrrlichtDevice *device)
+{
+#if defined(XORG_USED)
+#      if RUN_IN_PLACE
+       return setXorgWindowIconFromPath(device,
+                       path_share + "/misc/" PROJECT_NAME "-xorg-icon-128.png");
+#      else
+       // We have semi-support for reading in-place data if we are
+       // compiled with RUN_IN_PLACE. Don't break with this and
+       // also try the path_share location.
+       return
+               setXorgWindowIconFromPath(device,
+                       ICON_DIR "/hicolor/128x128/apps/" PROJECT_NAME ".png") ||
+               setXorgWindowIconFromPath(device,
+                       path_share + "/misc/" PROJECT_NAME "-xorg-icon-128.png");
+#      endif
+#elif defined(_WIN32)
+       const video::SExposedVideoData exposedData = device->getVideoDriver()->getExposedVideoData();
+       HWND hWnd; // Window handle
+
+       switch (device->getVideoDriver()->getDriverType()) {
+       case video::EDT_DIRECT3D8:
+               hWnd = reinterpret_cast<HWND>(exposedData.D3D8.HWnd);
+               break;
+       case video::EDT_DIRECT3D9:
+               hWnd = reinterpret_cast<HWND>(exposedData.D3D9.HWnd);
+               break;
+       case video::EDT_OPENGL:
+               hWnd = reinterpret_cast<HWND>(exposedData.OpenGLWin32.HWnd);
+               break;
+       default:
+               return false;
+       }
+
+       // Load the ICON from resource file
+       const HICON hicon = LoadIcon(
+               GetModuleHandle(NULL),
+               MAKEINTRESOURCE(130) // The ID of the ICON defined in winresource.rc
+       );
+
+       if (hicon) {
+               SendMessage(hWnd, WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(hicon));
+               SendMessage(hWnd, WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(hicon));
+               return true;
+       }
+       return false;
+#else
+       return false;
+#endif
+}
+
+bool setXorgWindowIconFromPath(IrrlichtDevice *device,
+       const std::string &icon_file)
+{
+#ifdef XORG_USED
+
+       video::IVideoDriver *v_driver = device->getVideoDriver();
+
+       video::IImageLoader *image_loader = NULL;
+       u32 cnt = v_driver->getImageLoaderCount();
+       for (u32 i = 0; i < cnt; i++) {
+               if (v_driver->getImageLoader(i)->isALoadableFileExtension(icon_file.c_str())) {
+                       image_loader = v_driver->getImageLoader(i);
+                       break;
+               }
+       }
+
+       if (!image_loader) {
+               warningstream << "Could not find image loader for file '"
+                       << icon_file << "'" << std::endl;
+               return false;
+       }
+
+       io::IReadFile *icon_f = device->getFileSystem()->createAndOpenFile(icon_file.c_str());
+
+       if (!icon_f) {
+               warningstream << "Could not load icon file '"
+                       << icon_file << "'" << std::endl;
+               return false;
+       }
+
+       video::IImage *img = image_loader->loadImage(icon_f);
+
+       if (!img) {
+               warningstream << "Could not load icon file '"
+                       << icon_file << "'" << std::endl;
+               icon_f->drop();
+               return false;
+       }
+
+       u32 height = img->getDimension().Height;
+       u32 width = img->getDimension().Width;
+
+       size_t icon_buffer_len = 2 + height * width;
+       long *icon_buffer = new long[icon_buffer_len];
+
+       icon_buffer[0] = width;
+       icon_buffer[1] = height;
+
+       for (u32 x = 0; x < width; x++) {
+               for (u32 y = 0; y < height; y++) {
+                       video::SColor col = img->getPixel(x, y);
+                       long pixel_val = 0;
+                       pixel_val |= (u8)col.getAlpha() << 24;
+                       pixel_val |= (u8)col.getRed() << 16;
+                       pixel_val |= (u8)col.getGreen() << 8;
+                       pixel_val |= (u8)col.getBlue();
+                       icon_buffer[2 + x + y * width] = pixel_val;
+               }
+       }
+
+       img->drop();
+       icon_f->drop();
+
+       const video::SExposedVideoData &video_data = v_driver->getExposedVideoData();
+
+       Display *x11_dpl = (Display *)video_data.OpenGLLinux.X11Display;
+
+       if (x11_dpl == NULL) {
+               warningstream << "Could not find x11 display for setting its icon."
+                       << std::endl;
+               delete [] icon_buffer;
+               return false;
+       }
+
+       Window x11_win = (Window)video_data.OpenGLLinux.X11Window;
+
+       Atom net_wm_icon = XInternAtom(x11_dpl, "_NET_WM_ICON", False);
+       Atom cardinal = XInternAtom(x11_dpl, "CARDINAL", False);
+       XChangeProperty(x11_dpl, x11_win,
+               net_wm_icon, cardinal, 32,
+               PropModeReplace, (const unsigned char *)icon_buffer,
+               icon_buffer_len);
+
+       delete [] icon_buffer;
+
+#endif
+       return true;
+}
 
 ////
 //// Video/Display Information (Client-only)
@@ -790,4 +929,31 @@ bool secure_rand_fill_buf(void *buf, size_t len)
 
 #endif
 
+void attachOrCreateConsole(void)
+{
+#ifdef _WIN32
+       static bool consoleAllocated = false;
+       const bool redirected = (_fileno(stdout) == -2 || _fileno(stdout) == -1); // If output is redirected to e.g a file
+       if (!consoleAllocated && redirected && (AttachConsole(ATTACH_PARENT_PROCESS) || AllocConsole())) {
+               freopen("CONOUT$", "w", stdout);
+               freopen("CONOUT$", "w", stderr);
+               consoleAllocated = true;
+       }
+#endif
+}
+
+// Load performance counter frequency only once at startup
+#ifdef _WIN32
+
+inline double get_perf_freq()
+{
+       LARGE_INTEGER freq;
+       QueryPerformanceFrequency(&freq);
+       return freq.QuadPart;
+}
+
+double perf_freq = get_perf_freq();
+
+#endif
+
 } //namespace porting