The Battle for Wesnoth  1.13.4+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 - 2016 by Ignacio Riquelme Morelle <[email protected]>
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  int child_status = 0;
68  const pid_t child = fork();
69 
70  if(child == -1) {
71  ERR_DU << "open_object(): fork() failed" << std::endl;
72  return false;
73  } else if(child == 0) {
74  execlp(launcher, launcher, path_or_url.c_str(), nullptr);
75  _exit(1); // This shouldn't happen.
76  } else if(waitpid(child, &child_status, 0) == -1) {
77  ERR_DU << "open_object(): waitpid() failed" << std::endl;
78  return false;
79  }
80 
81  if(child_status) {
82 //Those status check macros seem to trigger old style casts on some compiler versions
83 #pragma GCC diagnostic push
84 #pragma GCC diagnostic ignored "-Wold-style-cast"
85  if(WIFEXITED(child_status)) {
86  ERR_DU << "open_object(): " << launcher << " returned "
87  << WEXITSTATUS(child_status) << '\n';
88 #pragma GCC diagnostic pop
89  } else {
90  ERR_DU << "open_object(): " << launcher << " failed" << std::endl;
91  }
92 
93  return false;
94  }
95 
96  return true;
97 
98 #elif defined(_WIN32)
99 
100  LOG_DU << "open_object(): on Win32, will use ShellExecute()\n";
101 
102  std::wstring u16path = unicode_cast<std::wstring>(path_or_url);
103 
104  const ptrdiff_t res = reinterpret_cast<ptrdiff_t>(ShellExecute(nullptr, L"open", u16path.c_str(), nullptr, nullptr, SW_SHOW));
105  if(res <= 32) {
106  ERR_DU << "open_object(): ShellExecute() failed (" << res << ")" << std::endl;
107  return false;
108  }
109 
110  return true;
111 
112 #else
113 
114  UNUSED(path_or_url); // silence gcc's -Wunused-parameter
115  ERR_DU << "open_object(): unsupported platform" << std::endl;
116  return false;
117 
118 #endif
119 }
120 
121 }
#define ERR_DU
Definition: open.cpp:39
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:56
GLuint res
Definition: glew.h:9258
bool open_object_is_supported()
Returns whether open_object() is supported/implemented for the current platform.
Definition: open.cpp:44
Standard logging facilities (interface).
GLsizei const GLcharARB ** string
Definition: glew.h:4503
static lg::log_domain log_desktop("desktop")