The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
open.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2013 - 2025
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/wait.h>
26#include <unistd.h> // fork(), exec family
27
28#elif defined(_WIN32)
29
30#ifndef UNICODE
31#define UNICODE
32#endif
33#define WIN32_LEAN_AND_MEAN
34
35#include <windows.h>
36#include <shellapi.h> // ShellExecute()
37
38#elif defined(__ANDROID__)
39#include <SDL3/SDL_system.h> // For SDL Android functions
40#include <jni.h>
41
42#endif
43
44static lg::log_domain log_desktop("desktop");
45#define ERR_DU LOG_STREAM(err, log_desktop)
46#define LOG_DU LOG_STREAM(info, log_desktop)
47
48namespace desktop {
49
50bool open_object([[maybe_unused]] const std::string& path_or_url)
51{
52 LOG_DU << "open_object(): requested object: " << path_or_url;
53
54#if defined(_X11) || defined(__APPLE__)
55
56#ifndef __APPLE__
57 LOG_DU << "open_object(): on X11, will use xdg-open";
58 const char launcher[] = "xdg-open";
59#else
60 LOG_DU << "open_object(): on OS X, will use open";
61 const char launcher[] = "open";
62#endif
63
64 const pid_t child = fork();
65
66 if(child == -1) {
67 ERR_DU << "open_object(): fork() failed";
68 return false;
69 } else if(child == 0) {
70 execlp(launcher, launcher, path_or_url.c_str(), nullptr);
71 _exit(1); // This shouldn't happen.
72 }
73
74 std::thread t { [child](){ int status; waitpid(child, &status, 0); } };
75 t.detach();
76
77 return true;
78
79#elif defined(_WIN32)
80
81 LOG_DU << "open_object(): on Win32, will use ShellExecute()";
82
83 std::wstring u16path = unicode_cast<std::wstring>(path_or_url);
84
85 const ptrdiff_t res = reinterpret_cast<ptrdiff_t>(ShellExecute(nullptr, L"open", u16path.c_str(), nullptr, nullptr, SW_SHOW));
86 if(res <= 32) {
87 ERR_DU << "open_object(): ShellExecute() failed (" << res << ")";
88 return false;
89 }
90
91 return true;
92
93#elif defined(__ANDROID__)
94 LOG_DU << "open_object(): on Android, will use Intent.GET_ACTION_VIEW with path as extra data. URL: " << path_or_url;
95 // call the helper method WesnothActivity.open(String url) using JNI
96 JNIEnv* env = reinterpret_cast<JNIEnv*>(SDL_GetAndroidJNIEnv());
97 jobject wesnoth_instance = reinterpret_cast<jobject>(SDL_GetAndroidActivity());
98 jclass wesnoth_activity(env->GetObjectClass(wesnoth_instance));
99 jmethodID open = env->GetMethodID(wesnoth_activity, "open", "(Ljava/lang/String;)V");
100 env->CallVoidMethod(wesnoth_instance, open, env->NewStringUTF(path_or_url.c_str()));
101
102 if(env->ExceptionCheck() == JNI_TRUE) {
103 env->ExceptionDescribe();
104 env->ExceptionClear();
105 }
106
107 env->DeleteLocalRef(wesnoth_instance);
108 env->DeleteLocalRef(wesnoth_activity);
109
110 return true;
111#else
112
113 ERR_DU << "open_object(): unsupported platform";
114 return false;
115
116#endif
117}
118
119}
double t
#define LOG_DU
#define ERR_DU
Standard logging facilities (interface).
bool open_object(const std::string &path_or_url)
Opens the specified object with the default application configured for its type.
Definition open.cpp:50
static lg::log_domain log_desktop("desktop")
Desktop environment interaction functions.