mirror of
https://github.com/love2d/love.git
synced 2026-08-15 15:51:12 +02:00
Added love.system.openURL (resolves issue #863)
This commit is contained in:
Regular → Executable
+80
-3
@@ -18,8 +18,22 @@
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
**/
|
||||
|
||||
// LOVE
|
||||
#include "common/config.h"
|
||||
#include "System.h"
|
||||
|
||||
#if defined(LOVE_MACOSX)
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#elif defined(LOVE_LINUX)
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#elif defined(LOVE_WINDOWS)
|
||||
#include "common/utf8.h"
|
||||
#include <shlobj.h>
|
||||
#include <shellapi.h>
|
||||
#pragma comment(lib, "shell32.lib")
|
||||
#endif
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace system
|
||||
@@ -27,17 +41,80 @@ namespace system
|
||||
|
||||
std::string System::getOS() const
|
||||
{
|
||||
#ifdef LOVE_MACOSX
|
||||
#if defined(LOVE_MACOSX)
|
||||
return "OS X";
|
||||
#elif LOVE_WINDOWS
|
||||
#elif defined(LOVE_WINDOWS)
|
||||
return "Windows";
|
||||
#elif LOVE_LINUX
|
||||
#elif defined(LOVE_LINUX)
|
||||
return "Linux";
|
||||
#else
|
||||
return "Unknown";
|
||||
#endif
|
||||
}
|
||||
|
||||
bool System::openURL(const std::string &url) const
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
#if defined(LOVE_MACOSX)
|
||||
|
||||
// We could be lazy and use system("open " + url), but this is safer.
|
||||
CFURLRef cfurl = CFURLCreateWithBytes(nullptr,
|
||||
(const UInt8 *) url.c_str(),
|
||||
url.length(),
|
||||
kCFStringEncodingUTF8,
|
||||
nullptr);
|
||||
|
||||
success = LSOpenCFURLRef(cfurl, nullptr) == noErr;
|
||||
CFRelease(cfurl);
|
||||
|
||||
#elif defined(LOVE_LINUX)
|
||||
|
||||
// Spawn a child process, which we'll replace with xdg-open.
|
||||
pid_t pid = vfork();
|
||||
|
||||
if (pid == 0) // Child process.
|
||||
{
|
||||
// Replace the child process with xdg-open and pass in the URL.
|
||||
execlp("xdg-open", "xdg-open", url.c_str(), nullptr);
|
||||
|
||||
// exec will only return if it errored, so we should exit with non-zero.
|
||||
_exit(1);
|
||||
}
|
||||
else if (pid > 0) // Parent process.
|
||||
{
|
||||
// Wait for xdg-open to complete (or fail.)
|
||||
int status = 0;
|
||||
if (waitpid(pid, &status, 0) == pid)
|
||||
success = (status == 0);
|
||||
else
|
||||
success = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// vfork() failed.
|
||||
success = false;
|
||||
}
|
||||
|
||||
#elif defined(LOVE_WINDOWS)
|
||||
|
||||
// Unicode-aware WinAPI functions don't accept UTF-8, so we need to convert.
|
||||
std::wstring wurl = to_widestr(url);
|
||||
|
||||
HINSTANCE result = ShellExecuteW(nullptr,
|
||||
L"open",
|
||||
wurl.c_str(),
|
||||
nullptr,
|
||||
nullptr,
|
||||
SW_SHOW);
|
||||
|
||||
success = (int) result > 32;
|
||||
|
||||
#endif
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool System::getConstant(const char *in, System::PowerState &out)
|
||||
{
|
||||
return powerStates.find(in, out);
|
||||
|
||||
@@ -85,6 +85,16 @@ public:
|
||||
**/
|
||||
virtual PowerState getPowerInfo(int &seconds, int &percent) const = 0;
|
||||
|
||||
/**
|
||||
* Opens the specified URL with the user's default program to handle that
|
||||
* particular URL type.
|
||||
*
|
||||
* @param url The URL to open.
|
||||
*
|
||||
* @return Whether the URL was opened successfully.
|
||||
**/
|
||||
virtual bool openURL(const std::string &url) const;
|
||||
|
||||
static bool getConstant(const char *in, PowerState &out);
|
||||
static bool getConstant(PowerState in, const char *&out);
|
||||
|
||||
|
||||
@@ -79,6 +79,13 @@ int w_getPowerInfo(lua_State *L)
|
||||
return 3;
|
||||
}
|
||||
|
||||
int w_openURL(lua_State *L)
|
||||
{
|
||||
std::string url = luax_checkstring(L, 1);
|
||||
luax_pushboolean(L, instance->openURL(url));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const luaL_Reg functions[] =
|
||||
{
|
||||
{ "getOS", w_getOS },
|
||||
@@ -86,6 +93,7 @@ static const luaL_Reg functions[] =
|
||||
{ "setClipboardText", w_setClipboardText },
|
||||
{ "getClipboardText", w_getClipboardText },
|
||||
{ "getPowerInfo", w_getPowerInfo },
|
||||
{ "openURL", w_openURL },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ int w_getProcessorCount(lua_State *L);
|
||||
int w_setClipboardText(lua_State *L);
|
||||
int w_getClipboardText(lua_State *L);
|
||||
int w_getPowerInfo(lua_State *L);
|
||||
int w_openURL(lua_State *L);
|
||||
extern "C" LOVE_EXPORT int luaopen_love_system(lua_State *L);
|
||||
|
||||
} // system
|
||||
|
||||
Reference in New Issue
Block a user