From a9c3a423231e26ea3edee51d5f0bf949ca8e529b Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Sun, 17 May 2020 19:09:10 +0100 Subject: Add core.open_url() to main menu API (#8592) --- src/porting.cpp | 30 +++++++++++++++++++++++++++++- src/porting.h | 3 +++ src/porting_android.cpp | 12 ++++++++++++ src/porting_android.h | 2 ++ src/script/lua_api/l_mainmenu.cpp | 9 +++++++++ src/script/lua_api/l_mainmenu.h | 3 +++ 6 files changed, 58 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/porting.cpp b/src/porting.cpp index c0381ad06..ef1640467 100644 --- a/src/porting.cpp +++ b/src/porting.cpp @@ -33,22 +33,28 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include + #include #endif #if !defined(_WIN32) #include #include + #if !defined(__ANDROID__) + #include + #endif #endif #if defined(__hpux) #define _PSTAT64 #include #endif +#if defined(__ANDROID__) + #include "porting_android.h" +#endif #include "config.h" #include "debug.h" #include "filesys.h" #include "log.h" #include "util/string.h" -#include "settings.h" #include #include #include @@ -697,6 +703,28 @@ int mt_snprintf(char *buf, const size_t buf_size, const char *fmt, ...) return c; } +bool openURL(const std::string &url) +{ + if ((url.substr(0, 7) != "http://" && url.substr(0, 8) != "https://") || + url.find_first_of("\r\n") != std::string::npos) { + errorstream << "Invalid url: " << url << std::endl; + return false; + } + +#if defined(_WIN32) + return (intptr_t)ShellExecuteA(NULL, NULL, url.c_str(), NULL, NULL, SW_SHOWNORMAL) > 32; +#elif defined(__ANDROID__) + openURLAndroid(url); + return true; +#elif defined(__APPLE__) + const char *argv[] = {"open", url.c_str(), NULL}; + return posix_spawnp(NULL, "open", NULL, NULL, (char**)argv, environ) == 0; +#else + const char *argv[] = {"xdg-open", url.c_str(), NULL}; + return posix_spawnp(NULL, "xdg-open", NULL, NULL, (char**)argv, environ) == 0; +#endif +} + // Load performance counter frequency only once at startup #ifdef _WIN32 diff --git a/src/porting.h b/src/porting.h index 4d30a5970..f50f0a950 100644 --- a/src/porting.h +++ b/src/porting.h @@ -329,6 +329,9 @@ bool secure_rand_fill_buf(void *buf, size_t len); void attachOrCreateConsole(); int mt_snprintf(char *buf, const size_t buf_size, const char *fmt, ...); + +bool openURL(const std::string &url); + } // namespace porting #ifdef __ANDROID__ diff --git a/src/porting_android.cpp b/src/porting_android.cpp index 2c91df235..41b521ec2 100644 --- a/src/porting_android.cpp +++ b/src/porting_android.cpp @@ -213,6 +213,18 @@ void showInputDialog(const std::string &acceptButton, const std::string &hint, jacceptButton, jhint, jcurrent, jeditType); } +void openURLAndroid(const std::string &url) +{ + jmethodID url_open = jnienv->GetMethodID(nativeActivity, "openURL", + "(Ljava/lang/String;)V"); + + FATAL_ERROR_IF(url_open == nullptr, + "porting::openURLAndroid unable to find java openURL method"); + + jstring jurl = jnienv->NewStringUTF(url.c_str()); + jnienv->CallVoidMethod(app_global->activity->clazz, url_open, jurl); +} + int getInputDialogState() { jmethodID dialogstate = jnienv->GetMethodID(nativeActivity, diff --git a/src/porting_android.h b/src/porting_android.h index 42f90b60b..6eb054041 100644 --- a/src/porting_android.h +++ b/src/porting_android.h @@ -58,6 +58,8 @@ void initializePathsAndroid(); void showInputDialog(const std::string &acceptButton, const std::string &hint, const std::string ¤t, int editType); +void openURLAndroid(const std::string &url); + /** * WORKAROUND for not working callbacks from java -> c++ * get current state of input dialog diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index a76e9f079..f32c477c2 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/src/script/lua_api/l_mainmenu.cpp @@ -1063,6 +1063,14 @@ int ModApiMainMenu::l_get_max_supp_proto(lua_State *L) return 1; } +/******************************************************************************/ +int ModApiMainMenu::l_open_url(lua_State *L) +{ + std::string url = luaL_checkstring(L, 1); + lua_pushboolean(L, porting::openURL(url)); + return 1; +} + /******************************************************************************/ int ModApiMainMenu::l_do_async_callback(lua_State *L) { @@ -1125,6 +1133,7 @@ void ModApiMainMenu::Initialize(lua_State *L, int top) API_FCT(get_screen_info); API_FCT(get_min_supp_proto); API_FCT(get_max_supp_proto); + API_FCT(open_url); API_FCT(do_async_callback); } diff --git a/src/script/lua_api/l_mainmenu.h b/src/script/lua_api/l_mainmenu.h index b2ca49320..5a16b3bfe 100644 --- a/src/script/lua_api/l_mainmenu.h +++ b/src/script/lua_api/l_mainmenu.h @@ -145,6 +145,9 @@ private: static int l_get_max_supp_proto(lua_State *L); + // other + static int l_open_url(lua_State *L); + // async static int l_do_async_callback(lua_State *L); -- cgit v1.2.3