Skip to content

Commit

Permalink
First shot at desktop menu items.
Browse files Browse the repository at this point in the history
  • Loading branch information
icculus committed Feb 13, 2008
1 parent 5a4efda commit 0b92f06
Show file tree
Hide file tree
Showing 10 changed files with 285 additions and 30 deletions.
14 changes: 14 additions & 0 deletions docs.txt
Expand Up @@ -182,6 +182,20 @@ Here are the elements, and the attributes they can possess.

Setup.Package attributes:

vendor (no default, mustExist, mustBeString, cantBeEmpty)

This is a unique identifier for your organization. This should be in the
format "companyname.dom" ... the hope is that your primary website is
a unique identifier for your company. If your website is www.icculus.org,
you'd enter your vendor setting as "icculus.org" ... just the hostname and
top-level domain. This is used largely by the OS to maintain packages
(Mac OS X application bundles, vendor IDs for Unix desktop menus, etc).
This is, in theory, never shown to the user, so you don't need this to
actually exist as a website with meaningful content, so long as you can
reasonably assure that the string is unique and follows the "host.dom"
format.


id (no default, mustExist, mustBeString, cantBeEmpty)

This is a unique identifier for your package. Currently it is used as
Expand Down
1 change: 1 addition & 0 deletions examples/duke3d/scripts/config.lua
Expand Up @@ -22,6 +22,7 @@ end

Setup.Package
{
vendor = "icculus.org",
id = "duke3d",
description = "Duke Nukem 3D",
version = "1.5",
Expand Down
1 change: 1 addition & 0 deletions examples/ut3-dedicated/scripts/config.lua
Expand Up @@ -3,6 +3,7 @@ local _ = MojoSetup.translate

Setup.Package
{
vendor = "epicgames.com",
id = "ut3-dedicated",
description = "Unreal Tournament 3 Dedicated Server",
version = "3487",
Expand Down
16 changes: 16 additions & 0 deletions lua_glue.c
Expand Up @@ -1057,6 +1057,20 @@ static int luahook_platform_mkdir(lua_State *L)
} // luahook_platform_mkdir


static int luahook_platform_installdesktopmenuitem(lua_State *L)
{
const char *data = luaL_checkstring(L, 1);
return retvalBoolean(L, MojoPlatform_installDesktopMenuItem(data));
} // luahook_platform_installdesktopmenuitem


static int luahook_platform_uninstalldesktopmenuitem(lua_State *L)
{
const char *data = luaL_checkstring(L, 1);
return retvalBoolean(L, MojoPlatform_uninstallDesktopMenuItem(data));
} // luahook_platform_uninstalldesktopmenuitem


static int luahook_movefile(lua_State *L)
{
boolean retval = false;
Expand Down Expand Up @@ -1669,6 +1683,8 @@ boolean MojoLua_initLua(void)
set_cfunc(luaState, luahook_platform_isfile, "isfile");
set_cfunc(luaState, luahook_platform_symlink, "symlink");
set_cfunc(luaState, luahook_platform_mkdir, "mkdir");
set_cfunc(luaState, luahook_platform_installdesktopmenuitem, "installdesktopmenuitem");
set_cfunc(luaState, luahook_platform_uninstalldesktopmenuitem, "uninstalldesktopmenuitem");
lua_setfield(luaState, -2, "platform");

// Set the GUI functions...
Expand Down
14 changes: 14 additions & 0 deletions platform.h
Expand Up @@ -231,6 +231,20 @@ void MojoPlatform_dlclose(void *lib);
// the browser will inform the user if there's a problem loading the URL.
boolean MojoPlatform_launchBrowser(const char *url);

// Add a menu item to the Application menu or Start bar or whatever.
// (data) is 100% platform dependent right now, and this interface will
// likely change as we come to understand various systems' needs better.
// On Unix, it expects this to be a path to a FreeDesktop .desktop file.
// Returns (true) on success and (false) on failure.
boolean MojoPlatform_installDesktopMenuItem(const char *data);

// Remove a menu item from the Application menu or Start bar or whatever.
// (data) is 100% platform dependent right now, and this interface will
// likely change as we come to understand various systems' needs better.
// On Unix, it expects this to be a path to a FreeDesktop .desktop file.
// Returns (true) on success and (false) on failure.
boolean MojoPlatform_uninstallDesktopMenuItem(const char *data);

#if !SUPPORT_MULTIARCH
#define MojoPlatform_switchBin(img, len)
#else
Expand Down
63 changes: 54 additions & 9 deletions platform_unix.c
Expand Up @@ -26,7 +26,7 @@
#include <syslog.h>
#include <dirent.h>
#include <fcntl.h>
#include <wait.h>
#include <sys/wait.h>

#if MOJOSETUP_HAVE_SYS_UCRED_H
# ifdef MOJOSETUP_HAVE_MNTENT_H
Expand Down Expand Up @@ -1063,28 +1063,47 @@ static char *shellEscape(const char *str)
} // shellEscape


static boolean unix_launchBrowser(const char *url)
static boolean unix_launchXdgUtil(const char *util, const char **argv)
{
boolean retval = false;
char *path = findBinaryInPath("xdg-open");
char *path = findBinaryInPath(util);

if (path != NULL) // it's installed on the system; use that.
{
char *escapedurl = shellEscape(url);
char *cmd = format("xdg-open %0 >/dev/null 2>&1", escapedurl);
char *cmd = path;
char *tmp = NULL;
int i;
for (i = 0; argv[i]; i++)
{
char *escaped = shellEscape(argv[i]);
tmp = format("%0 %1", cmd, escaped);
free(escaped);
free(cmd);
cmd = tmp;
} // for

tmp = format("%0 >/dev/null 2>&1", cmd);
free(cmd);
cmd = tmp;
retval = (system(cmd) == 0);
free(cmd);
free(escapedurl);
free(path);
} // if

else // try our fallback copy of xdg-utils in GBaseArchive?
{
const char *argv[] = { url, NULL };
retval = (runScript("meta/xdg-utils/xdg-open", true, argv) == 0);
char *script = format("meta/xdg-utils/%0", util);
retval = (runScript(script, true, argv) == 0);
free(script);
} // if

return retval;
} // unix_launchXdgUtil


static boolean unix_launchBrowser(const char *url)
{
const char *argv[] = { url, NULL };
return unix_launchXdgUtil("xdg-open", argv);
} // unix_launchBrowser
#endif

Expand All @@ -1106,6 +1125,32 @@ boolean MojoPlatform_launchBrowser(const char *url)
} // MojoPlatform_launchBrowser


boolean MojoPlatform_installDesktopMenuItem(const char *data)
{
#if PLATFORM_MACOSX || PLATFORM_BEOS
// !!! FIXME: write me.
STUBBED("desktop menu support");
return false;
#else
const char *argv[] = { "install", data, NULL };
return unix_launchXdgUtil("xdg-desktop-menu", argv);
#endif
} // MojoPlatform_installDesktopMenuItem


boolean MojoPlatform_uninstallDesktopMenuItem(const char *data)
{
#if PLATFORM_MACOSX || PLATFORM_BEOS
// !!! FIXME: write me.
STUBBED("desktop menu support");
return false;
#else
const char *argv[] = { "uninstall", data, NULL };
return unix_launchXdgUtil("xdg-desktop-menu", argv);
#endif
} // MojoPlatform_uninstallDesktopMenuItem


#if SUPPORT_MULTIARCH
void MojoPlatform_switchBin(const uint8 *img, size_t len)
{
Expand Down
14 changes: 14 additions & 0 deletions scripts/config.lua
Expand Up @@ -35,6 +35,7 @@ end

Setup.Package
{
vendor = "com.mycompany",
id = "mygame",
description = "My Game",
version = "1.0",
Expand Down Expand Up @@ -131,6 +132,19 @@ Setup.Package
end
},

Setup.DesktopMenuItem
{
disabled = false,
name = "My Game",
genericname = "Shoot-em up",
comment = "A game for shooting aliens.",
builtin_icon = false,
icon = "icon.png", -- relative to the dest; you must install it!
commandline = "command-line",
categories = "Game",
mimetype = { 'application/x-mygame-map', 'application/x-mygame-url' },
},

-- Here's an option that has it's own EULA.
Setup.Option
{
Expand Down
19 changes: 19 additions & 0 deletions scripts/localization.lua
Expand Up @@ -303,6 +303,13 @@ MojoSetup.localization = {
nb = "FEIL: write_manifest krever støtte for Lua-parser",
};

-- This is shown if the config file wants us to add desktop menu items
-- but uninstaller support isn't enabled. This is considered bad taste
-- to add system menu items without a way to remove them. This is
-- a bug the developer must fix before shipping her installer.
["BUG: Setup.DesktopMenuItem requires support_uninstall"] = {
};

-- This is a file's permissions. Programmers give these as strings, and
-- if one isn't valid, the program will report this. So, on Unix, they
-- might specify "0600" as a valid string, but "sdfksjdfk" wouldn't be
Expand Down Expand Up @@ -1014,6 +1021,18 @@ MojoSetup.localization = {
["[Make the window taller!]"] = {
nb = "[Gjør vinduet høyere!]",
};

-- This is written out if we failed to add an item to the desktop
-- application menu (or "Start" bar on Windows, or maybe the Dock on
-- Mac OS X, etc).
["Failed to install desktop menu item"] = {
};

-- This is written out if we failed to remove an item from the desktop
-- application menu (or "Start" bar on Windows, or maybe the Dock on
-- Mac OS X, etc).
["Failed to uninstall desktop menu item"] = {
};
};

-- end of localization.lua ...
Expand Down
15 changes: 15 additions & 0 deletions scripts/mojosetup_init.lua
Expand Up @@ -245,6 +245,7 @@ function Setup.Package(tab)

tab = sanitize("Package", tab,
{
{ "vendor", nil, mustExist, mustBeString, cantBeEmpty },
{ "id", nil, mustExist, mustBeString, cantBeEmpty },
{ "disabled", nil, mustBeBool },
{ "description", nil, mustExist, mustBeString, cantBeEmpty },
Expand Down Expand Up @@ -406,6 +407,20 @@ function Setup.OptionGroup(tab)
})
end

function Setup.DesktopMenuItem(tab)
return sanitize("DesktopMenuItem", tab,
{
{ "disabled", nil, mustBeBool },
{ "name", nil, mustExist, mustBeString, cantBeEmpty },
{ "genericname", nil, mustExist, mustBeString, cantBeEmpty },
{ "comment", nil, mustExist, mustBeString, cantBeEmpty },
{ "builtin_icon", nil, mustBeBool },
{ "icon", nil, mustExist, mustBeString, cantBeEmpty },
{ "commandline", nil, mustExist, mustBeString, cantBeEmpty },
{ "category", nil, mustExist, mustBeStringOrTableOfStrings },
{ "mimetype", nil, mustBeStringOrTableOfStrings },
})
end

local function prepare_localization()
-- Map some legacy language identifiers into updated equivalents.
Expand Down

0 comments on commit 0b92f06

Please sign in to comment.