Barely-functioning GL playback with new arrangement.
[dcpomatic.git] / src / lib / cross.cc
index 831a1a2b2b0c2e1913646834d420c5e53c67b18c..5d35d5a4bbcb28da70ca7b77f0ceec678c1a826e 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2018 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -21,6 +21,8 @@
 #include "cross.h"
 #include "compose.hpp"
 #include "log.h"
+#include "dcpomatic_log.h"
+#include "config.h"
 #include "exceptions.h"
 extern "C" {
 #include <libavformat/avio.h>
@@ -34,6 +36,8 @@ extern "C" {
 #include <windows.h>
 #undef DATADIR
 #include <shlwapi.h>
+#include <shellapi.h>
+#include <fcntl.h>
 #endif
 #ifdef DCPOMATIC_OSX
 #include <sys/sysctl.h>
@@ -50,10 +54,6 @@ extern "C" {
 
 #include "i18n.h"
 
-#define LOG_GENERAL(...) log->log (String::compose (__VA_ARGS__), LogEntry::TYPE_GENERAL);
-#define LOG_ERROR(...) log->log (String::compose (__VA_ARGS__), LogEntry::TYPE_ERROR);
-#define LOG_ERROR_NC(...) log->log (__VA_ARGS__, LogEntry::TYPE_ERROR);
-
 using std::pair;
 using std::list;
 using std::ifstream;
@@ -65,7 +65,7 @@ using boost::shared_ptr;
 
 /** @param s Number of seconds to sleep for */
 void
-dcpomatic_sleep (int s)
+dcpomatic_sleep_seconds (int s)
 {
 #ifdef DCPOMATIC_POSIX
        sleep (s);
@@ -75,6 +75,17 @@ dcpomatic_sleep (int s)
 #endif
 }
 
+void
+dcpomatic_sleep_milliseconds (int ms)
+{
+#ifdef DCPOMATIC_POSIX
+       usleep (ms * 1000);
+#endif
+#ifdef DCPOMATIC_WINDOWS
+       Sleep (ms);
+#endif
+}
+
 /** @return A string of CPU information (model name etc.) */
 string
 cpu_info ()
@@ -179,7 +190,7 @@ shared_path ()
 }
 
 void
-run_ffprobe (boost::filesystem::path content, boost::filesystem::path out, shared_ptr<Log> log)
+run_ffprobe (boost::filesystem::path content, boost::filesystem::path out)
 {
 #ifdef DCPOMATIC_WINDOWS
        SECURITY_ATTRIBUTES security;
@@ -300,9 +311,17 @@ openssl_path ()
        boost::filesystem::path path = dir;
        path /= "openssl.exe";
        return path;
-#else
-       /* We assume that it's on the path for Linux and OS X */
-       return "openssl";
+#endif
+
+#ifdef DCPOMATIC_OSX
+       boost::filesystem::path path = app_contents();
+       path /= "MacOS";
+       path /= "openssl";
+       return path;
+#endif
+
+#ifdef DCPOMATIC_LINUX
+       return "dcpomatic2_openssl";
 #endif
 
 }
@@ -337,6 +356,7 @@ void
 Waker::nudge ()
 {
 #ifdef DCPOMATIC_WINDOWS
+       boost::mutex::scoped_lock lm (_mutex);
        SetThreadExecutionState (ES_SYSTEM_REQUIRED);
 #endif
 }
@@ -344,6 +364,7 @@ Waker::nudge ()
 Waker::Waker ()
 {
 #ifdef DCPOMATIC_OSX
+       boost::mutex::scoped_lock lm (_mutex);
        /* We should use this */
         // IOPMAssertionCreateWithName (kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, CFSTR ("Encoding DCP"), &_assertion_id);
        /* but it's not available on 10.5, so we use this */
@@ -354,15 +375,22 @@ Waker::Waker ()
 Waker::~Waker ()
 {
 #ifdef DCPOMATIC_OSX
+       boost::mutex::scoped_lock lm (_mutex);
        IOPMAssertionRelease (_assertion_id);
 #endif
 }
 
 void
-start_batch_converter (boost::filesystem::path dcpomatic)
+start_tool (boost::filesystem::path dcpomatic, string executable,
+#ifdef DCPOMATIC_OSX
+           string app
+#else
+           string
+#endif
+       )
 {
 #if defined(DCPOMATIC_LINUX) || defined(DCPOMATIC_WINDOWS)
-       boost::filesystem::path batch = dcpomatic.parent_path() / "dcpomatic2_batch";
+       boost::filesystem::path batch = dcpomatic.parent_path() / executable;
 #endif
 
 #ifdef DCPOMATIC_OSX
@@ -371,16 +399,15 @@ start_batch_converter (boost::filesystem::path dcpomatic)
        batch = batch.parent_path (); // Contents
        batch = batch.parent_path (); // DCP-o-matic.app
        batch = batch.parent_path (); // Applications
-       batch /= "DCP-o-matic\\ 2\\ Batch\\ Converter.app";
+       batch /= app;
        batch /= "Contents";
        batch /= "MacOS";
-       batch /= "dcpomatic2_batch";
+       batch /= executable;
 #endif
 
 #if defined(DCPOMATIC_LINUX) || defined(DCPOMATIC_OSX)
        pid_t pid = fork ();
        if (pid == 0) {
-               std::cout << "start " << batch << " from " << dcpomatic << "\n";
                int const r = system (batch.string().c_str());
                exit (WEXITSTATUS (r));
        }
@@ -400,6 +427,18 @@ start_batch_converter (boost::filesystem::path dcpomatic)
 #endif
 }
 
+void
+start_batch_converter (boost::filesystem::path dcpomatic)
+{
+       start_tool (dcpomatic, "dcpomatic2_batch", "DCP-o-matic\\ 2\\ Batch\\ Converter.app");
+}
+
+void
+start_player (boost::filesystem::path dcpomatic)
+{
+       start_tool (dcpomatic, "dcpomatic2_player", "DCP-o-matic\\ 2\\ Player.app");
+}
+
 uint64_t
 thread_id ()
 {
@@ -424,3 +463,76 @@ avio_open_boost (AVIOContext** s, boost::filesystem::path file, int flags)
        return avio_open (s, file.c_str(), flags);
 #endif
 }
+
+#ifdef DCPOMATIC_WINDOWS
+void
+maybe_open_console ()
+{
+       if (Config::instance()->win32_console ()) {
+               AllocConsole();
+
+               HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);
+               int hCrt = _open_osfhandle((intptr_t) handle_out, _O_TEXT);
+               FILE* hf_out = _fdopen(hCrt, "w");
+               setvbuf(hf_out, NULL, _IONBF, 1);
+               *stdout = *hf_out;
+
+               HANDLE handle_in = GetStdHandle(STD_INPUT_HANDLE);
+               hCrt = _open_osfhandle((intptr_t) handle_in, _O_TEXT);
+               FILE* hf_in = _fdopen(hCrt, "r");
+               setvbuf(hf_in, NULL, _IONBF, 128);
+               *stdin = *hf_in;
+       }
+}
+#endif
+
+boost::filesystem::path
+home_directory ()
+{
+#if defined(DCPOMATIC_LINUX) || defined(DCPOMATIC_OSX)
+               return getenv("HOME");
+#endif
+#ifdef DCPOMATIC_WINDOWS
+               return boost::filesystem::path(getenv("HOMEDRIVE")) / boost::filesystem::path(getenv("HOMEPATH"));
+#endif
+}
+
+string
+command_and_read (string cmd)
+{
+#ifdef DCPOMATIC_LINUX
+       FILE* pipe = popen (cmd.c_str(), "r");
+       if (!pipe) {
+               throw runtime_error ("popen failed");
+       }
+
+       string result;
+       char buffer[128];
+       try {
+               while (fgets(buffer, sizeof(buffer), pipe)) {
+                       result += buffer;
+               }
+       } catch (...) {
+               pclose (pipe);
+               throw;
+       }
+
+       pclose (pipe);
+       return result;
+#endif
+
+       return "";
+}
+
+/** @return true if this process is a 32-bit one running on a 64-bit-capable OS */
+bool
+running_32_on_64 ()
+{
+#ifdef DCPOMATIC_WINDOWS
+       BOOL p;
+       IsWow64Process (GetCurrentProcess(), &p);
+       return p;
+#endif
+       /* XXX: assuming nobody does this on Linux / OS X */
+       return false;
+}