The Battle for Wesnoth  1.17.0-dev
open.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2013 - 2021
3  by Iris Morelle <shadowm2006@gmail.com>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #include "desktop/open.hpp"
17 
18 #include "log.hpp"
20 
21 #if defined(_X11) || defined(__APPLE__)
22 
23 #include <thread>
24 
25 #include <sys/types.h>
26 #include <sys/wait.h>
27 #include <unistd.h> // fork(), exec family
28 
29 #elif defined(_WIN32)
30 
31 #ifndef UNICODE
32 #define UNICODE
33 #endif
34 #define WIN32_LEAN_AND_MEAN
35 
36 #include <windows.h>
37 #include <shellapi.h> // ShellExecute()
38 
39 #endif
40 
41 static lg::log_domain log_desktop("desktop");
42 #define ERR_DU LOG_STREAM(err, log_desktop)
43 #define LOG_DU LOG_STREAM(info, log_desktop)
44 
45 namespace desktop {
46 
47 bool open_object([[maybe_unused]] const std::string& path_or_url)
48 {
49  LOG_DU << "open_object(): requested object: " << path_or_url << '\n';
50 
51 #if defined(_X11) || defined(__APPLE__)
52 
53 #ifndef __APPLE__
54  LOG_DU << "open_object(): on X11, will use xdg-open\n";
55  const char launcher[] = "xdg-open";
56 #else
57  LOG_DU << "open_object(): on OS X, will use open\n";
58  const char launcher[] = "open";
59 #endif
60 
61  const pid_t child = fork();
62 
63  if(child == -1) {
64  ERR_DU << "open_object(): fork() failed" << std::endl;
65  return false;
66  } else if(child == 0) {
67  execlp(launcher, launcher, path_or_url.c_str(), nullptr);
68  _exit(1); // This shouldn't happen.
69  }
70 
71  std::thread t { [child](){ int status; waitpid(child, &status, 0); } };
72  t.detach();
73 
74  return true;
75 
76 #elif defined(_WIN32)
77 
78  LOG_DU << "open_object(): on Win32, will use ShellExecute()\n";
79 
80  std::wstring u16path = unicode_cast<std::wstring>(path_or_url);
81 
82  const ptrdiff_t res = reinterpret_cast<ptrdiff_t>(ShellExecute(nullptr, L"open", u16path.c_str(), nullptr, nullptr, SW_SHOW));
83  if(res <= 32) {
84  ERR_DU << "open_object(): ShellExecute() failed (" << res << ")" << std::endl;
85  return false;
86  }
87 
88  return true;
89 
90 #else
91 
92  ERR_DU << "open_object(): unsupported platform" << std::endl;
93  return false;
94 
95 #endif
96 }
97 
98 }
#define ERR_DU
Definition: open.cpp:42
ucs4_convert_impl::enableif< TD, typename TS::value_type >::type unicode_cast(const TS &source)
Desktop environment interaction functions.
#define LOG_DU
Definition: open.cpp:43
bool open_object([[maybe_unused]] const std::string &path_or_url)
Definition: open.cpp:47
double t
Definition: astarsearch.cpp:65
Standard logging facilities (interface).
static lg::log_domain log_desktop("desktop")