Added love.system.openURL (resolves issue #863)

This commit is contained in:
Alex Szpakowski
2014-03-31 16:13:05 -03:00
parent c985b1f2f7
commit 38497d23da
7 changed files with 132 additions and 4 deletions
Regular → Executable
+80 -3
View File
@@ -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);
+10
View File
@@ -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);
+8
View File
@@ -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 }
};
+1
View File
@@ -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