Add option to open a DCP in the player (#1312).
[dcpomatic.git] / src / lib / cross.cc
index 454fe044cb51b2e19b3c646ba4d87738cbf762dc..75205dc1aa11709d84b651421f452005e0399b6d 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.
 
 #include "cross.h"
 #include "compose.hpp"
 #include "log.h"
+#include "config.h"
 #include "exceptions.h"
+extern "C" {
+#include <libavformat/avio.h>
+}
 #include <boost/algorithm/string.hpp>
 #ifdef DCPOMATIC_LINUX
 #include <unistd.h>
@@ -31,6 +35,8 @@
 #include <windows.h>
 #undef DATADIR
 #include <shlwapi.h>
+#include <shellapi.h>
+#include <fcntl.h>
 #endif
 #ifdef DCPOMATIC_OSX
 #include <sys/sysctl.h>
@@ -356,10 +362,16 @@ Waker::~Waker ()
 }
 
 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
@@ -368,16 +380,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));
        }
@@ -397,6 +408,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 ()
 {
@@ -406,3 +429,40 @@ thread_id ()
        return (uint64_t) pthread_self ();
 #endif
 }
+
+int
+avio_open_boost (AVIOContext** s, boost::filesystem::path file, int flags)
+{
+#ifdef DCPOMATIC_WINDOWS
+       int const length = (file.string().length() + 1) * 2;
+       char* utf8 = new char[length];
+       WideCharToMultiByte (CP_UTF8, 0, file.c_str(), -1, utf8, length, 0, 0);
+       int const r = avio_open (s, utf8, flags);
+       delete[] utf8;
+       return r;
+#else
+       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