The Battle for Wesnoth  1.13.10+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
open.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2013 - 2017 by Ignacio Riquelme Morelle <shadowm2006@gmail.com>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #include "desktop/open.hpp"
16 
17 #include "log.hpp"
19 
20 #if defined(_X11) || defined(__APPLE__)
21 
22 #include <sys/types.h>
23 #include <sys/wait.h>
24 #include <unistd.h> // fork(), exec family
25 
26 #elif defined(_WIN32)
27 
28 #ifndef UNICODE
29 #define UNICODE
30 #endif
31 #define WIN32_LEAN_AND_MEAN
32 
33 #include <windows.h>
34 #include <shellapi.h> // ShellExecute()
35 
36 #endif
37 
38 static lg::log_domain log_desktop("desktop");
39 #define ERR_DU LOG_STREAM(err, log_desktop)
40 #define LOG_DU LOG_STREAM(info, log_desktop)
41 
42 namespace desktop {
43 
45 {
46 #if defined(_X11) || defined(__APPLE__) || defined(_WIN32)
47  return true;
48 #else
49  return false;
50 #endif
51 }
52 
53 bool open_object(const std::string& path_or_url)
54 {
55  LOG_DU << "open_object(): requested object: " << path_or_url << '\n';
56 
57 #if defined(_X11) || defined(__APPLE__)
58 
59 #ifndef __APPLE__
60  LOG_DU << "open_object(): on X11, will use xdg-open\n";
61  const char launcher[] = "xdg-open";
62 #else
63  LOG_DU << "open_object(): on OS X, will use open\n";
64  const char launcher[] = "open";
65 #endif
66 
67  const pid_t child = fork();
68 
69  if(child == -1) {
70  ERR_DU << "open_object(): fork() failed" << std::endl;
71  return false;
72  } else if(child == 0) {
73  execlp(launcher, launcher, path_or_url.c_str(), nullptr);
74  _exit(1); // This shouldn't happen.
75  }
76 
77  // Waiting for the child process to exit is unnecessary because we ignore SIGCHLD.
78  // See the manpage for wait(2).
79 
80  return true;
81 
82 #elif defined(_WIN32)
83 
84  LOG_DU << "open_object(): on Win32, will use ShellExecute()\n";
85 
86  std::wstring u16path = unicode_cast<std::wstring>(path_or_url);
87 
88  const ptrdiff_t res = reinterpret_cast<ptrdiff_t>(ShellExecute(nullptr, L"open", u16path.c_str(), nullptr, nullptr, SW_SHOW));
89  if(res <= 32) {
90  ERR_DU << "open_object(): ShellExecute() failed (" << res << ")" << std::endl;
91  return false;
92  }
93 
94  return true;
95 
96 #else
97 
98  UNUSED(path_or_url); // silence gcc's -Wunused-parameter
99  ERR_DU << "open_object(): unsupported platform" << std::endl;
100  return false;
101 
102 #endif
103 }
104 
105 }
#define ERR_DU
Definition: open.cpp:39
std::vector< char_t > string
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:40
bool open_object(const std::string &path_or_url)
Opens the specified object with the default application configured for its type.
Definition: open.cpp:53
#define UNUSED(x)
Definition: global.hpp:49
bool open_object_is_supported()
Returns whether open_object() is supported/implemented for the current platform.
Definition: open.cpp:44
Standard logging facilities (interface).
static lg::log_domain log_desktop("desktop")