mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-08-26 23:13:13 +02:00
2567 lines
72 KiB
C++
2567 lines
72 KiB
C++
/*
|
|
* neutrino-mp lua to c++ bridge
|
|
*
|
|
* (C) 2013-2014 Stefan Seyfried <seife@tuxboxcvs.slipkontur.de>
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <config.h>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <unistd.h>
|
|
|
|
#include <global.h>
|
|
#include <system/debug.h>
|
|
#include <system/helpers.h>
|
|
#include <system/settings.h>
|
|
#include <system/set_threadname.h>
|
|
#include <gui/widget/msgbox.h>
|
|
#include <gui/widget/messagebox.h>
|
|
#include <gui/widget/keyboard_input.h>
|
|
#include <gui/filebrowser.h>
|
|
#include <gui/movieplayer.h>
|
|
#include <driver/pictureviewer/pictureviewer.h>
|
|
#include <neutrino.h>
|
|
|
|
#include "luainstance.h"
|
|
#include <video.h>
|
|
|
|
/* the magic color that tells us we are using one of the palette colors */
|
|
#define MAGIC_COLOR 0x42424200
|
|
#define MAGIC_MASK 0xFFFFFF00
|
|
|
|
struct table_key {
|
|
const char *name;
|
|
lua_Integer code;
|
|
};
|
|
|
|
struct table_key_u {
|
|
const char *name;
|
|
lua_Unsigned code;
|
|
};
|
|
|
|
struct lua_envexport {
|
|
const char *name;
|
|
table_key *t;
|
|
};
|
|
|
|
struct lua_envexport_u {
|
|
const char *name;
|
|
table_key_u *t;
|
|
};
|
|
|
|
static void set_lua_variables(lua_State *L)
|
|
{
|
|
/* keyname table created with
|
|
* sed -n '/^[[:space:]]*RC_0/,/^[[:space:]]*RC_analog_off/ {
|
|
* s#^[[:space:]]*RC_\([^[:space:]]*\).*# { "\1", CRCInput::RC_\1 },#p
|
|
* }' driver/rcinput.h
|
|
*/
|
|
static table_key keyname[] =
|
|
{
|
|
{ "0", CRCInput::RC_0 },
|
|
{ "1", CRCInput::RC_1 },
|
|
{ "2", CRCInput::RC_2 },
|
|
{ "3", CRCInput::RC_3 },
|
|
{ "4", CRCInput::RC_4 },
|
|
{ "5", CRCInput::RC_5 },
|
|
{ "6", CRCInput::RC_6 },
|
|
{ "7", CRCInput::RC_7 },
|
|
{ "8", CRCInput::RC_8 },
|
|
{ "9", CRCInput::RC_9 },
|
|
{ "backspace", CRCInput::RC_backspace },
|
|
{ "up", CRCInput::RC_up },
|
|
{ "left", CRCInput::RC_left },
|
|
{ "right", CRCInput::RC_right },
|
|
{ "down", CRCInput::RC_down },
|
|
{ "spkr", CRCInput::RC_spkr },
|
|
{ "minus", CRCInput::RC_minus },
|
|
{ "plus", CRCInput::RC_plus },
|
|
{ "standby", CRCInput::RC_standby },
|
|
{ "help", CRCInput::RC_help },
|
|
{ "home", CRCInput::RC_home },
|
|
{ "setup", CRCInput::RC_setup },
|
|
{ "topleft", CRCInput::RC_topleft },
|
|
{ "topright", CRCInput::RC_topright },
|
|
{ "page_up", CRCInput::RC_page_up },
|
|
{ "page_down", CRCInput::RC_page_down },
|
|
{ "ok", CRCInput::RC_ok },
|
|
{ "red", CRCInput::RC_red },
|
|
{ "green", CRCInput::RC_green },
|
|
{ "yellow", CRCInput::RC_yellow },
|
|
{ "blue", CRCInput::RC_blue },
|
|
{ "top_left", CRCInput::RC_top_left },
|
|
{ "top_right", CRCInput::RC_top_right },
|
|
{ "bottom_left", CRCInput::RC_bottom_left },
|
|
{ "bottom_right", CRCInput::RC_bottom_right },
|
|
{ "audio", CRCInput::RC_audio },
|
|
{ "video", CRCInput::RC_video },
|
|
{ "tv", CRCInput::RC_tv },
|
|
{ "radio", CRCInput::RC_radio },
|
|
{ "text", CRCInput::RC_text },
|
|
{ "info", CRCInput::RC_info },
|
|
{ "epg", CRCInput::RC_epg },
|
|
{ "recall", CRCInput::RC_recall },
|
|
{ "favorites", CRCInput::RC_favorites },
|
|
{ "sat", CRCInput::RC_sat },
|
|
{ "sat2", CRCInput::RC_sat2 },
|
|
{ "record", CRCInput::RC_record },
|
|
{ "play", CRCInput::RC_play },
|
|
{ "pause", CRCInput::RC_pause },
|
|
{ "forward", CRCInput::RC_forward },
|
|
{ "rewind", CRCInput::RC_rewind },
|
|
{ "stop", CRCInput::RC_stop },
|
|
{ "timeshift", CRCInput::RC_timeshift },
|
|
{ "mode", CRCInput::RC_mode },
|
|
{ "games", CRCInput::RC_games },
|
|
{ "next", CRCInput::RC_next },
|
|
{ "prev", CRCInput::RC_prev },
|
|
{ "www", CRCInput::RC_www },
|
|
{ "power_on", CRCInput::RC_power_on },
|
|
{ "power_off", CRCInput::RC_power_off },
|
|
{ "standby_on", CRCInput::RC_standby_on },
|
|
{ "standby_off", CRCInput::RC_standby_off },
|
|
{ "mute_on", CRCInput::RC_mute_on },
|
|
{ "mute_off", CRCInput::RC_mute_off },
|
|
{ "analog_on", CRCInput::RC_analog_on },
|
|
{ "analog_off", CRCInput::RC_analog_off },
|
|
#if 0
|
|
{ "find", CRCInput::RC_find },
|
|
{ "pip", CRCInput::RC_pip },
|
|
{ "folder", CRCInput::RC_archive },
|
|
{ "forward", CRCInput::RC_fastforward },
|
|
{ "slow", CRCInput::RC_slow },
|
|
{ "playmode", CRCInput::RC_playmode },
|
|
{ "usb", CRCInput::RC_usb },
|
|
{ "f1", CRCInput::RC_f1 },
|
|
{ "f2", CRCInput::RC_f2 },
|
|
{ "f3", CRCInput::RC_f3 },
|
|
{ "f4", CRCInput::RC_f4 },
|
|
{ "prog1", CRCInput::RC_prog1 },
|
|
{ "prog2", CRCInput::RC_prog2 },
|
|
{ "prog3", CRCInput::RC_prog3 },
|
|
{ "prog4", CRCInput::RC_prog4 },
|
|
#endif
|
|
/* to check if it is in our range */
|
|
{ "MaxRC", CRCInput::RC_MaxRC },
|
|
{ NULL, 0 }
|
|
};
|
|
|
|
/* list of colors, exported e.g. as COL['INFOBAR_SHADOW'] */
|
|
static table_key_u colorlist[] =
|
|
{
|
|
{ "COLORED_EVENTS_CHANNELLIST", MAGIC_COLOR | (COL_COLORED_EVENTS_CHANNELLIST) },
|
|
{ "COLORED_EVENTS_INFOBAR", MAGIC_COLOR | (COL_COLORED_EVENTS_INFOBAR) },
|
|
{ "INFOBAR_SHADOW", MAGIC_COLOR | (COL_INFOBAR_SHADOW) },
|
|
{ "INFOBAR", MAGIC_COLOR | (COL_INFOBAR) },
|
|
{ "MENUHEAD", MAGIC_COLOR | (COL_MENUHEAD) },
|
|
{ "MENUCONTENT", MAGIC_COLOR | (COL_MENUCONTENT) },
|
|
{ "MENUCONTENTDARK", MAGIC_COLOR | (COL_MENUCONTENTDARK) },
|
|
{ "MENUCONTENTSELECTED", MAGIC_COLOR | (COL_MENUCONTENTSELECTED) },
|
|
{ "MENUCONTENTINACTIVE", MAGIC_COLOR | (COL_MENUCONTENTINACTIVE) },
|
|
{ "BACKGROUND", MAGIC_COLOR | (COL_BACKGROUND) },
|
|
{ "DARK_RED", MAGIC_COLOR | (COL_DARK_RED0) },
|
|
{ "DARK_GREEN", MAGIC_COLOR | (COL_DARK_GREEN0) },
|
|
{ "DARK_BLUE", MAGIC_COLOR | (COL_DARK_BLUE0) },
|
|
{ "LIGHT_GRAY", MAGIC_COLOR | (COL_LIGHT_GRAY0) },
|
|
{ "DARK_GRAY", MAGIC_COLOR | (COL_DARK_GRAY0) },
|
|
{ "RED", MAGIC_COLOR | (COL_RED0) },
|
|
{ "GREEN", MAGIC_COLOR | (COL_GREEN0) },
|
|
{ "YELLOW", MAGIC_COLOR | (COL_YELLOW0) },
|
|
{ "BLUE", MAGIC_COLOR | (COL_BLUE0) },
|
|
{ "PURP", MAGIC_COLOR | (COL_PURP0) },
|
|
{ "LIGHT_BLUE", MAGIC_COLOR | (COL_LIGHT_BLUE0) },
|
|
{ "WHITE", MAGIC_COLOR | (COL_WHITE0) },
|
|
{ "BLACK", MAGIC_COLOR | (COL_BLACK0) },
|
|
{ "COLORED_EVENTS_TEXT", (lua_Unsigned) (COL_COLORED_EVENTS_TEXT) },
|
|
{ "INFOBAR_TEXT", (lua_Unsigned) (COL_INFOBAR_TEXT) },
|
|
{ "INFOBAR_SHADOW_TEXT", (lua_Unsigned) (COL_INFOBAR_SHADOW_TEXT) },
|
|
{ "MENUHEAD_TEXT", (lua_Unsigned) (COL_MENUHEAD_TEXT) },
|
|
{ "MENUCONTENT_TEXT", (lua_Unsigned) (COL_MENUCONTENT_TEXT) },
|
|
{ "MENUCONTENT_TEXT_PLUS_1", (lua_Unsigned) (COL_MENUCONTENT_TEXT_PLUS_1) },
|
|
{ "MENUCONTENT_TEXT_PLUS_2", (lua_Unsigned) (COL_MENUCONTENT_TEXT_PLUS_2) },
|
|
{ "MENUCONTENT_TEXT_PLUS_3", (lua_Unsigned) (COL_MENUCONTENT_TEXT_PLUS_3) },
|
|
{ "MENUCONTENTDARK_TEXT", (lua_Unsigned) (COL_MENUCONTENTDARK_TEXT) },
|
|
{ "MENUCONTENTDARK_TEXT_PLUS_1", (lua_Unsigned) (COL_MENUCONTENTDARK_TEXT_PLUS_1) },
|
|
{ "MENUCONTENTDARK_TEXT_PLUS_2", (lua_Unsigned) (COL_MENUCONTENTDARK_TEXT_PLUS_2) },
|
|
{ "MENUCONTENTSELECTED_TEXT", (lua_Unsigned) (COL_MENUCONTENTSELECTED_TEXT) },
|
|
{ "MENUCONTENTSELECTED_TEXT_PLUS_1", (lua_Unsigned) (COL_MENUCONTENTSELECTED_TEXT_PLUS_1) },
|
|
{ "MENUCONTENTSELECTED_TEXT_PLUS_2", (lua_Unsigned) (COL_MENUCONTENTSELECTED_TEXT_PLUS_2) },
|
|
{ "MENUCONTENTINACTIVE_TEXT", (lua_Unsigned) (COL_MENUCONTENTINACTIVE_TEXT) },
|
|
{ "MENUHEAD_PLUS_0", (lua_Unsigned) (COL_MENUHEAD_PLUS_0) },
|
|
{ "MENUCONTENT_PLUS_0", (lua_Unsigned) (COL_MENUCONTENT_PLUS_0) },
|
|
{ "MENUCONTENT_PLUS_1", (lua_Unsigned) (COL_MENUCONTENT_PLUS_1) },
|
|
{ "MENUCONTENT_PLUS_2", (lua_Unsigned) (COL_MENUCONTENT_PLUS_2) },
|
|
{ "MENUCONTENT_PLUS_3", (lua_Unsigned) (COL_MENUCONTENT_PLUS_3) },
|
|
{ "MENUCONTENT_PLUS_4", (lua_Unsigned) (COL_MENUCONTENT_PLUS_4) },
|
|
{ "MENUCONTENT_PLUS_5", (lua_Unsigned) (COL_MENUCONTENT_PLUS_5) },
|
|
{ "MENUCONTENT_PLUS_6", (lua_Unsigned) (COL_MENUCONTENT_PLUS_6) },
|
|
{ "MENUCONTENT_PLUS_7", (lua_Unsigned) (COL_MENUCONTENT_PLUS_7) },
|
|
{ "MENUCONTENTDARK_PLUS_0", (lua_Unsigned) (COL_MENUCONTENTDARK_PLUS_0) },
|
|
{ "MENUCONTENTDARK_PLUS_2", (lua_Unsigned) (COL_MENUCONTENTDARK_PLUS_2) },
|
|
{ "MENUCONTENTSELECTED_PLUS_0", (lua_Unsigned) (COL_MENUCONTENTSELECTED_PLUS_0) },
|
|
{ "MENUCONTENTSELECTED_PLUS_2", (lua_Unsigned) (COL_MENUCONTENTSELECTED_PLUS_2) },
|
|
{ "MENUCONTENTINACTIVE_PLUS_0", (lua_Unsigned) (COL_MENUCONTENTINACTIVE_PLUS_0) },
|
|
{ NULL, 0 }
|
|
};
|
|
|
|
/* font list, the _TYPE_ is redundant, exported e.g. as FONT['MENU'] */
|
|
static table_key fontlist[] =
|
|
{
|
|
{ "MENU", SNeutrinoSettings::FONT_TYPE_MENU },
|
|
{ "MENU_TITLE", SNeutrinoSettings::FONT_TYPE_MENU_TITLE },
|
|
{ "MENU_INFO", SNeutrinoSettings::FONT_TYPE_MENU_INFO },
|
|
{ "EPG_TITLE", SNeutrinoSettings::FONT_TYPE_EPG_TITLE },
|
|
{ "EPG_INFO1", SNeutrinoSettings::FONT_TYPE_EPG_INFO1 },
|
|
{ "EPG_INFO2", SNeutrinoSettings::FONT_TYPE_EPG_INFO2 },
|
|
{ "EPG_DATE", SNeutrinoSettings::FONT_TYPE_EPG_DATE },
|
|
{ "EVENTLIST_TITLE", SNeutrinoSettings::FONT_TYPE_EVENTLIST_TITLE },
|
|
{ "EVENTLIST_ITEMLARGE",SNeutrinoSettings::FONT_TYPE_EVENTLIST_ITEMLARGE },
|
|
{ "EVENTLIST_ITEMSMALL",SNeutrinoSettings::FONT_TYPE_EVENTLIST_ITEMSMALL },
|
|
{ "EVENTLIST_DATETIME", SNeutrinoSettings::FONT_TYPE_EVENTLIST_DATETIME },
|
|
{ "CHANNELLIST", SNeutrinoSettings::FONT_TYPE_CHANNELLIST },
|
|
{ "CHANNELLIST_DESCR", SNeutrinoSettings::FONT_TYPE_CHANNELLIST_DESCR },
|
|
{ "CHANNELLIST_NUMBER", SNeutrinoSettings::FONT_TYPE_CHANNELLIST_NUMBER },
|
|
{ "CHANNELLIST_EVENT", SNeutrinoSettings::FONT_TYPE_CHANNELLIST_EVENT },
|
|
{ "CHANNEL_NUM_ZAP", SNeutrinoSettings::FONT_TYPE_CHANNEL_NUM_ZAP },
|
|
{ "INFOBAR_NUMBER", SNeutrinoSettings::FONT_TYPE_INFOBAR_NUMBER },
|
|
{ "INFOBAR_CHANNAME", SNeutrinoSettings::FONT_TYPE_INFOBAR_CHANNAME },
|
|
{ "INFOBAR_INFO", SNeutrinoSettings::FONT_TYPE_INFOBAR_INFO },
|
|
{ "INFOBAR_SMALL", SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL },
|
|
{ "FILEBROWSER_ITEM", SNeutrinoSettings::FONT_TYPE_FILEBROWSER_ITEM },
|
|
{ "MENU_HINT", SNeutrinoSettings::FONT_TYPE_MENU_HINT },
|
|
{ NULL, 0 }
|
|
};
|
|
|
|
table_key corners[] =
|
|
{
|
|
{ "TOP_LEFT", CORNER_TOP_LEFT },
|
|
{ "TOP_RIGHT", CORNER_TOP_RIGHT },
|
|
{ "BOTTOM_LEFT", CORNER_BOTTOM_LEFT },
|
|
{ "BOTTOM_RIGHT", CORNER_BOTTOM_RIGHT },
|
|
{ "RADIUS_LARGE", RADIUS_LARGE }, /* those depend on g_settings.rounded_corners */
|
|
{ "RADIUS_MID", RADIUS_MID },
|
|
{ "RADIUS_SMALL", RADIUS_SMALL },
|
|
{ "RADIUS_MIN", RADIUS_MIN },
|
|
{ NULL, 0 }
|
|
};
|
|
|
|
/* screen offsets, exported as e.g. SCREEN['END_Y'] */
|
|
table_key screenopts[] =
|
|
{
|
|
{ "OFF_X", g_settings.screen_StartX },
|
|
{ "OFF_Y", g_settings.screen_StartY },
|
|
{ "END_X", g_settings.screen_EndX },
|
|
{ "END_Y", g_settings.screen_EndY },
|
|
{ NULL, 0 }
|
|
};
|
|
table_key menureturn[] =
|
|
{
|
|
{ "NONE", menu_return::RETURN_NONE },
|
|
{ "REPAINT", menu_return::RETURN_REPAINT },
|
|
{ "EXIT", menu_return::RETURN_EXIT },
|
|
{ "EXIT_ALL", menu_return::RETURN_EXIT_ALL },
|
|
{ "EXIT_REPAINT", menu_return::RETURN_EXIT_REPAINT },
|
|
{ NULL, 0 }
|
|
};
|
|
|
|
/* list of environment variable arrays to be exported */
|
|
lua_envexport e[] =
|
|
{
|
|
{ "RC", keyname },
|
|
{ "SCREEN", screenopts },
|
|
{ "FONT", fontlist },
|
|
{ "CORNER", corners },
|
|
{ "MENU_RETURN", menureturn },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
int i = 0;
|
|
while (e[i].name) {
|
|
int j = 0;
|
|
lua_newtable(L);
|
|
while (e[i].t[j].name) {
|
|
lua_pushstring(L, e[i].t[j].name);
|
|
lua_pushinteger(L, e[i].t[j].code);
|
|
lua_settable(L, -3);
|
|
j++;
|
|
}
|
|
lua_setglobal(L, e[i].name);
|
|
i++;
|
|
}
|
|
|
|
lua_envexport_u e_u[] =
|
|
{
|
|
{ "COL", colorlist },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
i = 0;
|
|
while (e_u[i].name) {
|
|
int j = 0;
|
|
lua_newtable(L);
|
|
while (e_u[i].t[j].name) {
|
|
lua_pushstring(L, e_u[i].t[j].name);
|
|
lua_pushunsigned(L, e_u[i].t[j].code);
|
|
lua_settable(L, -3);
|
|
j++;
|
|
}
|
|
lua_setglobal(L, e_u[i].name);
|
|
i++;
|
|
}
|
|
}
|
|
|
|
//#define DBG printf
|
|
#define DBG(...)
|
|
|
|
#define lua_boxpointer(L, u) \
|
|
(*(void **)(lua_newuserdata(L, sizeof(void *))) = (u))
|
|
|
|
#define lua_unboxpointer(L, i) \
|
|
(*(void **)(lua_touserdata(L, i)))
|
|
|
|
const char CLuaInstance::className[] = "neutrino";
|
|
|
|
CLuaInstance::CLuaInstance()
|
|
{
|
|
/* Create the intepreter object. */
|
|
lua = luaL_newstate();
|
|
|
|
/* register standard + custom functions. */
|
|
registerFunctions();
|
|
}
|
|
|
|
CLuaInstance::~CLuaInstance()
|
|
{
|
|
if (lua != NULL)
|
|
{
|
|
lua_close(lua);
|
|
lua = NULL;
|
|
}
|
|
}
|
|
|
|
/* Ported by Benny Chen, http://www.bennychen.cn/tag/lual_checkbool/ */
|
|
bool CLuaInstance::_luaL_checkbool(lua_State *L, int numArg)
|
|
{
|
|
bool b = false;
|
|
if (lua_isboolean(L, numArg))
|
|
b = lua_toboolean(L, numArg);
|
|
else {
|
|
lua_Debug ar;
|
|
lua_getstack(L, 0, &ar);
|
|
lua_getinfo(L, "n", &ar);
|
|
luaL_error(L, "bad argument #%d to '%s' (%s expected, got %s)\n",
|
|
numArg-1, ar.name,
|
|
lua_typename(L, LUA_TBOOLEAN),
|
|
lua_typename(L, lua_type(L, numArg)));
|
|
}
|
|
return b;
|
|
}
|
|
|
|
void CLuaInstance::paramBoolDeprecated(lua_State *L, const char* val)
|
|
{
|
|
lua_Debug ar;
|
|
lua_getstack(L, 1, &ar);
|
|
lua_getinfo(L, "Sl", &ar);
|
|
printf("[Lua Script] \33[1;31m%s\33[0m %s (\33[31m\"%s\"\33[0m)\n %s \33[32mtrue\33[0m.\n (%s:%d)\n",
|
|
g_Locale->getText(LOCALE_LUA_BOOLPARAM_DEPRECATED1),
|
|
g_Locale->getText(LOCALE_LUA_BOOLPARAM_DEPRECATED2), val,
|
|
g_Locale->getText(LOCALE_LUA_BOOLPARAM_DEPRECATED3),
|
|
ar.short_src, ar.currentline);
|
|
}
|
|
|
|
void CLuaInstance::functionDeprecated(lua_State *L, const char* oldFunc, const char* newFunc)
|
|
{
|
|
lua_Debug ar;
|
|
lua_getstack(L, 1, &ar);
|
|
lua_getinfo(L, "Sl", &ar);
|
|
printf("[Lua Script] \33[1;31m%s\33[0m %s \33[33m%s\33[0m %s \33[1;33m%s\33[0m.\n (%s:%d)\n",
|
|
g_Locale->getText(LOCALE_LUA_FUNCTION_DEPRECATED1),
|
|
g_Locale->getText(LOCALE_LUA_FUNCTION_DEPRECATED2), oldFunc,
|
|
g_Locale->getText(LOCALE_LUA_FUNCTION_DEPRECATED3), newFunc,
|
|
ar.short_src, ar.currentline);
|
|
}
|
|
|
|
lua_Unsigned CLuaInstance::checkMagicMask(lua_Unsigned col)
|
|
{
|
|
if ((col & MAGIC_MASK) == MAGIC_COLOR)
|
|
/* use the color constants */
|
|
col = CFrameBuffer::getInstance()->realcolor[col & 0x000000ff];
|
|
return col;
|
|
}
|
|
|
|
#define SET_VAR1(NAME) \
|
|
lua_pushinteger(lua, NAME); \
|
|
lua_setglobal(lua, #NAME);
|
|
#define SET_VAR2(NAME, VALUE) \
|
|
lua_pushinteger(lua, VALUE); \
|
|
lua_setglobal(lua, #NAME);
|
|
|
|
/* Run the given script. */
|
|
void CLuaInstance::runScript(const char *fileName, std::vector<std::string> *argv, std::string *result_code, std::string *result_string, std::string *error_string)
|
|
{
|
|
// luaL_dofile(lua, fileName);
|
|
/* run the script */
|
|
int status = luaL_loadfile(lua, fileName);
|
|
if (status) {
|
|
fprintf(stderr, "[CLuaInstance::%s] Can't load file: %s\n", __func__, lua_tostring(lua, -1));
|
|
ShowMsg2UTF("Lua script error:", lua_tostring(lua, -1), CMsgBox::mbrBack, CMsgBox::mbBack);
|
|
if (error_string)
|
|
*error_string = std::string(lua_tostring(lua, -1));
|
|
return;
|
|
}
|
|
int argvSize = 1;
|
|
int n = 0;
|
|
set_lua_variables(lua);
|
|
if (argv && (!argv->empty()))
|
|
argvSize += argv->size();
|
|
lua_createtable(lua, argvSize, 0);
|
|
|
|
// arg0 is scriptname
|
|
lua_pushstring(lua, fileName);
|
|
lua_rawseti(lua, -2, n++);
|
|
|
|
if (argv && (!argv->empty())) {
|
|
for(std::vector<std::string>::iterator it = argv->begin(); it != argv->end(); ++it) {
|
|
lua_pushstring(lua, it->c_str());
|
|
lua_rawseti(lua, -2, n++);
|
|
}
|
|
}
|
|
lua_setglobal(lua, "arg");
|
|
status = lua_pcall(lua, 0, LUA_MULTRET, 0);
|
|
if (result_code)
|
|
*result_code = to_string(status);
|
|
if (result_string && lua_isstring(lua, -1))
|
|
*result_string = std::string(lua_tostring(lua, -1));
|
|
if (status)
|
|
{
|
|
fprintf(stderr, "[CLuaInstance::%s] error in script: %s\n", __func__, lua_tostring(lua, -1));
|
|
ShowMsg2UTF("Lua script error:", lua_tostring(lua, -1), CMsgBox::mbrBack, CMsgBox::mbBack);
|
|
if (error_string)
|
|
*error_string = std::string(lua_tostring(lua, -1));
|
|
}
|
|
}
|
|
|
|
// Example: runScript(fileName, "Arg1", "Arg2", "Arg3", ..., NULL);
|
|
// Type of all parameters: const char*
|
|
// The last parameter to NULL is imperative.
|
|
void CLuaInstance::runScript(const char *fileName, const char *arg0, ...)
|
|
{
|
|
int i = 0;
|
|
std::vector<std::string> args;
|
|
args.push_back(arg0);
|
|
va_list list;
|
|
va_start(list, arg0);
|
|
const char* temp = va_arg(list, const char*);
|
|
while (temp != NULL) {
|
|
if (i >= 64) {
|
|
fprintf(stderr, "CLuaInstance::runScript: too many arguments!\n");
|
|
args.clear();
|
|
va_end(list);
|
|
return;
|
|
}
|
|
args.push_back(temp);
|
|
temp = va_arg(list, const char*);
|
|
i++;
|
|
}
|
|
va_end(list);
|
|
runScript(fileName, &args);
|
|
args.clear();
|
|
}
|
|
|
|
static void abortHook(lua_State *lua, lua_Debug *)
|
|
{
|
|
luaL_error(lua, "aborted");
|
|
}
|
|
|
|
void CLuaInstance::abortScript()
|
|
{
|
|
lua_sethook(lua, &abortHook, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
|
|
}
|
|
|
|
const luaL_Reg CLuaInstance::methods[] =
|
|
{
|
|
{ "PaintBox", CLuaInstance::PaintBox },
|
|
{ "RenderString", CLuaInstance::RenderString },
|
|
{ "PaintIcon", CLuaInstance::PaintIcon },
|
|
{ "GetInput", CLuaInstance::GetInput },
|
|
{ "FontHeight", CLuaInstance::FontHeight },
|
|
{ "getRenderWidth", CLuaInstance::getRenderWidth },
|
|
{ "GetSize", CLuaInstance::GetSize },
|
|
{ "DisplayImage", CLuaInstance::DisplayImage },
|
|
{ "setBlank", CLuaInstance::setBlank },
|
|
{ "ShowPicture", CLuaInstance::ShowPicture },
|
|
{ "StopPicture", CLuaInstance::StopPicture },
|
|
{ "Blit", CLuaInstance::Blit },
|
|
{ "GetLanguage", CLuaInstance::GetLanguage },
|
|
{ "runScript", CLuaInstance::runScriptExt },
|
|
{ "PlayFile", CLuaInstance::PlayFile },
|
|
{ "strFind", CLuaInstance::strFind },
|
|
{ "strSub", CLuaInstance::strSub },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
#ifdef STATIC_LUAPOSIX
|
|
/* hack: we link against luaposix, which is included in our
|
|
* custom built lualib */
|
|
extern "C" { LUAMOD_API int (luaopen_posix_c) (lua_State *L); }
|
|
#else
|
|
static int dolibrary (lua_State *L, const char *name)
|
|
{
|
|
int status = 0;
|
|
const char *msg = "";
|
|
lua_getglobal(L, "require");
|
|
lua_pushstring(L, name);
|
|
status = lua_pcall(L, 1, 0, 0);
|
|
if (status && !lua_isnil(L, -1))
|
|
{
|
|
msg = lua_tostring(L, -1);
|
|
if (NULL == msg)
|
|
{
|
|
msg = "(error object is not a string)";
|
|
}
|
|
fprintf(stderr, "[CLuaInstance::%s] error in dolibrary: %s (%s)\n", __func__, name,msg);
|
|
lua_pop(L, 1);
|
|
}
|
|
else
|
|
{
|
|
printf("[CLuaInstance::%s] loaded library: %s\n", __func__, name);
|
|
}
|
|
return status;
|
|
}
|
|
#endif
|
|
/* load basic functions and register our own C callbacks */
|
|
void CLuaInstance::registerFunctions()
|
|
{
|
|
luaL_openlibs(lua);
|
|
luaopen_table(lua);
|
|
luaopen_io(lua);
|
|
luaopen_string(lua);
|
|
luaopen_math(lua);
|
|
#ifdef STATIC_LUAPOSIX
|
|
luaopen_posix_c(lua);
|
|
#else
|
|
dolibrary(lua,"posix");
|
|
#endif
|
|
|
|
lua_newtable(lua);
|
|
int methodtable = lua_gettop(lua);
|
|
luaL_newmetatable(lua, className);
|
|
int metatable = lua_gettop(lua);
|
|
lua_pushliteral(lua, "__metatable");
|
|
lua_pushvalue(lua, methodtable);
|
|
lua_settable(lua, metatable);
|
|
|
|
lua_pushliteral(lua, "__index");
|
|
lua_pushvalue(lua, methodtable);
|
|
lua_settable(lua, metatable);
|
|
|
|
lua_pushliteral(lua, "__gc");
|
|
lua_pushcfunction(lua, GCWindow);
|
|
lua_settable(lua, metatable);
|
|
|
|
lua_pop(lua, 1);
|
|
|
|
luaL_setfuncs(lua, methods, 0);
|
|
lua_pop(lua, 1);
|
|
|
|
lua_register(lua, className, NewWindow);
|
|
MenuRegister(lua);
|
|
HintboxRegister(lua);
|
|
MessageboxRegister(lua);
|
|
CWindowRegister(lua);
|
|
ComponentsTextRegister(lua);
|
|
SignalBoxRegister(lua);
|
|
CPictureRegister(lua);
|
|
LuaConfigFileRegister(lua);
|
|
}
|
|
|
|
CLuaData *CLuaInstance::CheckData(lua_State *L, int narg)
|
|
{
|
|
luaL_checktype(L, narg, LUA_TUSERDATA);
|
|
void *ud = luaL_checkudata(L, narg, className);
|
|
if (!ud)
|
|
fprintf(stderr, "[CLuaInstance::%s] wrong type %p, %d, %s\n", __func__, L, narg, className);
|
|
return *(CLuaData **)ud; // unbox pointer
|
|
}
|
|
|
|
int CLuaInstance::NewWindow(lua_State *L)
|
|
{
|
|
int count = lua_gettop(L);
|
|
int x = g_settings.screen_StartX;
|
|
int y = g_settings.screen_StartY;
|
|
int w = g_settings.screen_EndX - x;
|
|
int h = g_settings.screen_EndY - y;
|
|
CLuaData *D = new CLuaData();
|
|
if (count > 0)
|
|
x = luaL_checkint(L, 1);
|
|
if (count > 1)
|
|
y = luaL_checkint(L, 2);
|
|
if (count > 2)
|
|
w = luaL_checkint(L, 3);
|
|
if (count > 3)
|
|
h = luaL_checkint(L, 4);
|
|
CFBWindow *W = new CFBWindow(x, y, w, h);
|
|
D->fbwin = W;
|
|
D->rcinput = g_RCInput;
|
|
lua_boxpointer(L, D);
|
|
luaL_getmetatable(L, className);
|
|
lua_setmetatable(L, -2);
|
|
return 1;
|
|
}
|
|
|
|
int CLuaInstance::PaintBox(lua_State *L)
|
|
{
|
|
int count = lua_gettop(L);
|
|
DBG("CLuaInstance::%s %d\n", __func__, count);
|
|
int x, y, w, h, radius = 0, corner = CORNER_ALL;
|
|
unsigned int c;
|
|
|
|
CLuaData *W = CheckData(L, 1);
|
|
if (!W || !W->fbwin)
|
|
return 0;
|
|
x = luaL_checkint(L, 2);
|
|
y = luaL_checkint(L, 3);
|
|
w = luaL_checkint(L, 4);
|
|
h = luaL_checkint(L, 5);
|
|
/* luaL_checkint does not like e.g. 0xffcc0000 on powerpc (returns INT_MAX) instead */
|
|
c = (unsigned int)luaL_checknumber(L, 6);
|
|
if (count > 6)
|
|
radius = luaL_checkint(L, 7);
|
|
if (count > 7)
|
|
corner = luaL_checkint(L, 8);
|
|
/* those checks should be done in CFBWindow instead... */
|
|
if (x < 0)
|
|
x = 0;
|
|
if (y < 0)
|
|
y = 0;
|
|
if (w < 0 || x + w > W->fbwin->dx)
|
|
w = W->fbwin->dx - x;
|
|
if (h < 0 || y + h > W->fbwin->dy)
|
|
h = W->fbwin->dy - y;
|
|
checkMagicMask(c);
|
|
W->fbwin->paintBoxRel(x, y, w, h, c, radius, corner);
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::PaintIcon(lua_State *L)
|
|
{
|
|
DBG("CLuaInstance::%s %d\n", __func__, lua_gettop(L));
|
|
int x, y, h;
|
|
unsigned int o;
|
|
const char *fname;
|
|
|
|
CLuaData *W = CheckData(L, 1);
|
|
if (!W || !W->fbwin)
|
|
return 0;
|
|
fname = luaL_checkstring(L, 2);
|
|
x = luaL_checkint(L, 3);
|
|
y = luaL_checkint(L, 4);
|
|
h = luaL_checkint(L, 5);
|
|
o = luaL_checkint(L, 6);
|
|
W->fbwin->paintIcon(fname, x, y, h, o);
|
|
return 0;
|
|
}
|
|
|
|
extern CPictureViewer * g_PicViewer;
|
|
|
|
int CLuaInstance::DisplayImage(lua_State *L)
|
|
{
|
|
DBG("CLuaInstance::%s %d\n", __func__, lua_gettop(L));
|
|
int x, y, w, h;
|
|
const char *fname;
|
|
|
|
fname = luaL_checkstring(L, 2);
|
|
x = luaL_checkint(L, 3);
|
|
y = luaL_checkint(L, 4);
|
|
w = luaL_checkint(L, 5);
|
|
h = luaL_checkint(L, 6);
|
|
int trans = 0;
|
|
if (lua_isnumber(L, 7))
|
|
trans = luaL_checkint(L, 7);
|
|
g_PicViewer->DisplayImage(fname, x, y, w, h, trans);
|
|
return 0;
|
|
}
|
|
|
|
extern cVideo * videoDecoder;
|
|
|
|
int CLuaInstance::setBlank(lua_State *L)
|
|
{
|
|
bool enable = true;
|
|
int numargs = lua_gettop(L);
|
|
if (numargs > 1)
|
|
enable = _luaL_checkbool(L, 2);
|
|
videoDecoder->setBlank(enable);
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::ShowPicture(lua_State *L)
|
|
{
|
|
const char *fname = luaL_checkstring(L, 2);
|
|
videoDecoder->ShowPicture(fname);
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::StopPicture(lua_State */*L*/)
|
|
{
|
|
videoDecoder->StopPicture();
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::PlayFile(lua_State *L)
|
|
{
|
|
printf("CLuaInstance::%s %d\n", __func__, lua_gettop(L));
|
|
int numargs = lua_gettop(L);
|
|
|
|
if (numargs < 3) {
|
|
printf("CLuaInstance::%s: not enough arguments (%d, expected 3)\n", __func__, numargs);
|
|
return 0;
|
|
}
|
|
const char *title;
|
|
const char *info1 = "";
|
|
const char *info2 = "";
|
|
const char *fname;
|
|
|
|
title = luaL_checkstring(L, 2);
|
|
fname = luaL_checkstring(L, 3);
|
|
if (numargs > 3)
|
|
info1 = luaL_checkstring(L, 4);
|
|
if (numargs > 4)
|
|
info2 = luaL_checkstring(L, 5);
|
|
printf("CLuaInstance::%s: title %s file %s\n", __func__, title, fname);
|
|
std::string st(title);
|
|
std::string si1(info1);
|
|
std::string si2(info2);
|
|
std::string sf(fname);
|
|
CMoviePlayerGui::getInstance().SetFile(st, sf, si1, si2);
|
|
CMoviePlayerGui::getInstance().exec(NULL, "http");
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::strFind(lua_State *L)
|
|
{
|
|
int numargs = lua_gettop(L);
|
|
if (numargs < 3) {
|
|
printf("CLuaInstance::%s: not enough arguments (%d, expected 2 (or 3 or 4))\n", __func__, numargs);
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
const char *s1;
|
|
const char *s2;
|
|
int pos=0, n=0, ret=0;
|
|
s1 = luaL_checkstring(L, 2);
|
|
s2 = luaL_checkstring(L, 3);
|
|
if (numargs > 3)
|
|
pos = luaL_checkint(L, 4);
|
|
if (numargs > 4)
|
|
n = luaL_checkint(L, 5);
|
|
|
|
std::string str(s1);
|
|
if (numargs > 4)
|
|
ret = str.find(s2, pos, n);
|
|
else
|
|
ret = str.find(s2, pos);
|
|
|
|
// printf("####[%s:%d] str_len: %d, s2: %s, pos: %d, n: %d, ret: %d\n", __func__, __LINE__, str.length(), s2, pos, n, ret);
|
|
if (ret == (int)std::string::npos)
|
|
lua_pushnil(L);
|
|
else
|
|
lua_pushinteger(L, ret);
|
|
return 1;
|
|
}
|
|
|
|
int CLuaInstance::strSub(lua_State *L)
|
|
{
|
|
int numargs = lua_gettop(L);
|
|
if (numargs < 3) {
|
|
printf("CLuaInstance::%s: not enough arguments (%d, expected 2 (or 3))\n", __func__, numargs);
|
|
lua_pushstring(L, "");
|
|
return 1;
|
|
}
|
|
const char *s1;
|
|
int pos = 0, len = (int)std::string::npos;
|
|
std::string ret="";
|
|
s1 = luaL_checkstring(L, 2);
|
|
pos = luaL_checkint(L, 3);
|
|
if (numargs > 3)
|
|
len = luaL_checkint(L, 4);
|
|
|
|
std::string str(s1);
|
|
ret = str.substr(pos, len);
|
|
|
|
// printf("####[%s:%d] str_len: %d, pos: %d, len: %d, ret_len: %d\n", __func__, __LINE__, str.length(), pos, len, ret.length());
|
|
lua_pushstring(L, ret.c_str());
|
|
return 1;
|
|
}
|
|
|
|
int CLuaInstance::GetSize(lua_State *L)
|
|
{
|
|
DBG("CLuaInstance::%s %d\n", __func__, lua_gettop(L));
|
|
int w = 0, h = 0;
|
|
const char *fname;
|
|
|
|
fname = luaL_checkstring(L, 2);
|
|
g_PicViewer->getSize(fname, &w, &h);
|
|
lua_pushinteger(L, w);
|
|
lua_pushinteger(L, h);
|
|
return 2;
|
|
}
|
|
|
|
int CLuaInstance::RenderString(lua_State *L)
|
|
{
|
|
int x, y, w, boxh, f, center;
|
|
unsigned int c;
|
|
const char *text;
|
|
int numargs = lua_gettop(L);
|
|
DBG("CLuaInstance::%s %d\n", __func__, numargs);
|
|
c = COL_MENUCONTENT_TEXT;
|
|
boxh = 0;
|
|
center = 0;
|
|
|
|
CLuaData *W = CheckData(L, 1);
|
|
if (!W || !W->fbwin)
|
|
return 0;
|
|
f = luaL_checkint(L, 2); /* font number, use FONT_TYPE_XXX in the script */
|
|
text = luaL_checkstring(L, 3); /* text */
|
|
x = luaL_checkint(L, 4);
|
|
y = luaL_checkint(L, 5);
|
|
if (numargs > 5)
|
|
c = luaL_checkint(L, 6);
|
|
if (numargs > 6)
|
|
w = luaL_checkint(L, 7);
|
|
else
|
|
w = W->fbwin->dx - x;
|
|
if (numargs > 7)
|
|
boxh = luaL_checkint(L, 8);
|
|
if (numargs > 8)
|
|
center = luaL_checkint(L, 9);
|
|
if (f >= SNeutrinoSettings::FONT_TYPE_COUNT || f < 0)
|
|
f = SNeutrinoSettings::FONT_TYPE_MENU;
|
|
int rwidth = g_Font[f]->getRenderWidth(text);
|
|
if (center) { /* center the text inside the box */
|
|
if (rwidth < w)
|
|
x += (w - rwidth) / 2;
|
|
}
|
|
checkMagicMask(c);
|
|
if (boxh > -1) /* if boxh < 0, don't paint string */
|
|
W->fbwin->RenderString(g_Font[f], x, y, w, text, c, boxh);
|
|
lua_pushinteger(L, rwidth); /* return renderwidth */
|
|
return 1;
|
|
}
|
|
|
|
int CLuaInstance::getRenderWidth(lua_State *L)
|
|
{
|
|
int f;
|
|
const char *text;
|
|
DBG("CLuaInstance::%s %d\n", __func__, lua_gettop(L));
|
|
|
|
CLuaData *W = CheckData(L, 1);
|
|
if (!W)
|
|
return 0;
|
|
f = luaL_checkint(L, 2); /* font number, use FONT['xxx'] for FONT_TYPE_xxx in the script */
|
|
text = luaL_checkstring(L, 3); /* text */
|
|
if (f >= SNeutrinoSettings::FONT_TYPE_COUNT || f < 0)
|
|
f = SNeutrinoSettings::FONT_TYPE_MENU;
|
|
|
|
lua_pushinteger(L, (int)g_Font[f]->getRenderWidth(text));
|
|
return 1;
|
|
}
|
|
|
|
int CLuaInstance::GetInput(lua_State *L)
|
|
{
|
|
int numargs = lua_gettop(L);
|
|
int timeout = 0;
|
|
neutrino_msg_t msg;
|
|
neutrino_msg_data_t data;
|
|
CLuaData *W = CheckData(L, 1);
|
|
if (!W)
|
|
return 0;
|
|
if (numargs > 1)
|
|
timeout = luaL_checkint(L, 2);
|
|
W->rcinput->getMsg_ms(&msg, &data, timeout);
|
|
/* TODO: I'm not sure if this works... */
|
|
if (msg != CRCInput::RC_timeout && msg > CRCInput::RC_MaxRC)
|
|
{
|
|
DBG("CLuaInstance::%s: msg 0x%08" PRIx32 " data 0x%08" PRIx32 "\n", __func__, msg, data);
|
|
CNeutrinoApp::getInstance()->handleMsg(msg, data);
|
|
}
|
|
/* signed int is debatable, but the "big" messages can't yet be handled
|
|
* inside lua scripts anyway. RC_timeout == -1, RC_nokey == -2 */
|
|
lua_pushinteger(L, (int)msg);
|
|
lua_pushunsigned(L, data);
|
|
return 2;
|
|
}
|
|
|
|
int CLuaInstance::FontHeight(lua_State *L)
|
|
{
|
|
int f;
|
|
DBG("CLuaInstance::%s %d\n", __func__, lua_gettop(L));
|
|
|
|
CLuaData *W = CheckData(L, 1);
|
|
if (!W)
|
|
return 0;
|
|
f = luaL_checkint(L, 2); /* font number, use FONT['xxx'] for FONT_TYPE_xxx in the script */
|
|
if (f >= SNeutrinoSettings::FONT_TYPE_COUNT || f < 0)
|
|
f = SNeutrinoSettings::FONT_TYPE_MENU;
|
|
lua_pushinteger(L, (int)g_Font[f]->getHeight());
|
|
return 1;
|
|
}
|
|
|
|
int CLuaInstance::GCWindow(lua_State *L)
|
|
{
|
|
DBG("CLuaInstance::%s %d\n", __func__, lua_gettop(L));
|
|
CLuaData *w = (CLuaData *)lua_unboxpointer(L, 1);
|
|
delete w->fbwin;
|
|
w->rcinput = NULL;
|
|
delete w;
|
|
return 0;
|
|
}
|
|
|
|
#if 1
|
|
int CLuaInstance::Blit(lua_State *)
|
|
{
|
|
return 0;
|
|
}
|
|
#else
|
|
int CLuaInstance::Blit(lua_State *L)
|
|
{
|
|
CLuaData *W = CheckData(L, 1);
|
|
if (W && W->fbwin) {
|
|
if (lua_isnumber(L, 2))
|
|
W->fbwin->blit((int)lua_tonumber(L, 2)); // enable/disable automatic blit
|
|
else
|
|
W->fbwin->blit();
|
|
}
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
int CLuaInstance::GetLanguage(lua_State *L)
|
|
{
|
|
// FIXME -- should conform to ISO 639-1/ISO 3166-1
|
|
lua_pushstring(L, g_settings.language.c_str());
|
|
|
|
return 1;
|
|
}
|
|
|
|
int CLuaInstance::runScriptExt(lua_State *L)
|
|
{
|
|
CLuaData *W = CheckData(L, 1);
|
|
if (!W) return 0;
|
|
|
|
int numargs = lua_gettop(L);
|
|
const char *script = luaL_checkstring(L, 2);
|
|
std::vector<std::string> args;
|
|
for (int i = 3; i <= numargs; i++) {
|
|
std::string arg = luaL_checkstring(L, i);
|
|
if (!arg.empty())
|
|
args.push_back(arg);
|
|
}
|
|
|
|
CLuaInstance *lua = new CLuaInstance();
|
|
lua->runScript(script, &args);
|
|
args.clear();
|
|
delete lua;
|
|
return 0;
|
|
}
|
|
|
|
bool CLuaInstance::tableLookup(lua_State *L, const char *what, std::string &value)
|
|
{
|
|
bool res = false;
|
|
lua_pushstring(L, what);
|
|
lua_gettable(L, -2);
|
|
res = lua_isstring(L, -1);
|
|
if (res)
|
|
value = lua_tostring(L, -1);
|
|
lua_pop(L, 1);
|
|
return res;
|
|
}
|
|
|
|
bool CLuaInstance::tableLookup(lua_State *L, const char *what, lua_Integer &value)
|
|
{
|
|
bool res = false;
|
|
lua_pushstring(L, what);
|
|
lua_gettable(L, -2);
|
|
res = lua_isnumber(L, -1);
|
|
if (res)
|
|
value = (lua_Integer) lua_tonumber(L, -1);
|
|
lua_pop(L, 1);
|
|
return res;
|
|
}
|
|
|
|
bool CLuaInstance::tableLookup(lua_State *L, const char *what, lua_Unsigned &value)
|
|
{
|
|
bool res = false;
|
|
lua_pushstring(L, what);
|
|
lua_gettable(L, -2);
|
|
res = lua_isnumber(L, -1);
|
|
if (res)
|
|
value = (lua_Unsigned) lua_tonumber(L, -1);
|
|
lua_pop(L, 1);
|
|
return res;
|
|
}
|
|
|
|
bool CLuaInstance::tableLookup(lua_State *L, const char *what, void** value)
|
|
{
|
|
bool res = false;
|
|
lua_pushstring(L, what);
|
|
lua_gettable(L, -2);
|
|
res = lua_isuserdata(L, -1);
|
|
if (res)
|
|
*value = lua_unboxpointer(L, -1);
|
|
lua_pop(L, 1);
|
|
return res;
|
|
}
|
|
|
|
bool CLuaInstance::tableLookup(lua_State *L, const char *what, bool &value)
|
|
{
|
|
bool res = false;
|
|
lua_pushstring(L, what);
|
|
lua_gettable(L, -2);
|
|
res = lua_isboolean(L, -1);
|
|
if (res)
|
|
value = lua_toboolean(L, -1);
|
|
lua_pop(L, 1);
|
|
return res;
|
|
}
|
|
|
|
bool CLuaMenuChangeObserver::changeNotify(lua_State *L, const std::string &luaAction, const std::string &luaId, void *Data)
|
|
{
|
|
const char *optionValue = (const char *) Data;
|
|
lua_pushglobaltable(L);
|
|
lua_getfield(L, -1, luaAction.c_str());
|
|
lua_remove(L, -2);
|
|
lua_pushstring(L, luaId.c_str());
|
|
lua_pushstring(L, optionValue);
|
|
lua_pcall(L, 2 /* two args */, 1 /* one result */, 0);
|
|
double res = lua_isnumber(L, -1) ? lua_tonumber(L, -1) : 0;
|
|
return (((int)res == menu_return::RETURN_REPAINT) || ((int)res == menu_return::RETURN_EXIT_REPAINT));
|
|
}
|
|
|
|
void CLuaInstance::MenuRegister(lua_State *L)
|
|
{
|
|
luaL_Reg meth[] = {
|
|
{ "new", CLuaInstance::MenuNew },
|
|
{ "addKey", CLuaInstance::MenuAddKey },
|
|
{ "addItem", CLuaInstance::MenuAddItem },
|
|
{ "exec", CLuaInstance::MenuExec },
|
|
{ "hide", CLuaInstance::MenuHide },
|
|
{ "__gc", CLuaInstance::MenuDelete },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
luaL_newmetatable(L, "menu");
|
|
luaL_setfuncs(L, meth, 0);
|
|
lua_pushvalue(L, -1);
|
|
lua_setfield(L, -1, "__index");
|
|
lua_setglobal(L, "menu");
|
|
|
|
// keep misspelled "menue" for backwards-compatibility
|
|
luaL_newmetatable(L, "menu");
|
|
luaL_setfuncs(L, meth, 0);
|
|
lua_pushvalue(L, -1);
|
|
lua_setfield(L, -1, "__index");
|
|
lua_setglobal(L, "menue");
|
|
}
|
|
|
|
CLuaMenu *CLuaInstance::MenuCheck(lua_State *L, int n)
|
|
{
|
|
return *(CLuaMenu **) luaL_checkudata(L, n, "menu");
|
|
}
|
|
|
|
CLuaMenu::CLuaMenu()
|
|
{
|
|
m = NULL;
|
|
observ = new CLuaMenuChangeObserver();
|
|
}
|
|
|
|
CLuaMenu::~CLuaMenu()
|
|
{
|
|
delete m;
|
|
delete observ;
|
|
}
|
|
|
|
CLuaMenuForwarder::CLuaMenuForwarder(lua_State *_L, std::string _luaAction, std::string _luaId)
|
|
{
|
|
L = _L;
|
|
luaAction = _luaAction;
|
|
luaId = _luaId;
|
|
}
|
|
|
|
CLuaMenuForwarder::~CLuaMenuForwarder()
|
|
{
|
|
}
|
|
|
|
int CLuaMenuForwarder::exec(CMenuTarget* /*parent*/, const std::string & /*actionKey*/)
|
|
{
|
|
int res = menu_return::RETURN_REPAINT;
|
|
if (!luaAction.empty()){
|
|
lua_pushglobaltable(L);
|
|
lua_getfield(L, -1, luaAction.c_str());
|
|
lua_remove(L, -2);
|
|
lua_pushstring(L, luaId.c_str());
|
|
int status = lua_pcall(L, 1 /* one arg */, 1 /* one result */, 0);
|
|
if (status) {
|
|
fprintf(stderr, "[CLuaMenuForwarder::%s] error in script: %s\n", __func__, lua_tostring(L, -1));
|
|
ShowMsg2UTF("Lua script error:", lua_tostring(L, -1), CMsgBox::mbrBack, CMsgBox::mbBack);
|
|
}
|
|
if (lua_isnumber(L, -1))
|
|
res = (int) lua_tonumber(L, -1);
|
|
lua_pop(L, 1);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
CLuaMenuFilebrowser::CLuaMenuFilebrowser(lua_State *_L, std::string _luaAction, std::string _luaId, std::string *_value, bool _dirMode) : CLuaMenuForwarder(_L, _luaAction, _luaId)
|
|
{
|
|
value = _value;
|
|
dirMode = _dirMode;
|
|
}
|
|
|
|
int CLuaMenuFilebrowser::exec(CMenuTarget* /*parent*/, const std::string& /*actionKey*/)
|
|
{
|
|
CFileBrowser fileBrowser;
|
|
fileBrowser.Dir_Mode = dirMode;
|
|
|
|
CFileFilter fileFilter;
|
|
for (std::vector<std::string>::iterator it = filter.begin(); it != filter.end(); ++it)
|
|
fileFilter.addFilter(*it);
|
|
if (!filter.empty())
|
|
fileBrowser.Filter = &fileFilter;
|
|
|
|
if (fileBrowser.exec(value->c_str()) == true)
|
|
*value = fileBrowser.getSelectedFile()->Name;
|
|
|
|
if (!luaAction.empty()){
|
|
lua_pushglobaltable(L);
|
|
lua_getfield(L, -1, luaAction.c_str());
|
|
lua_remove(L, -2);
|
|
lua_pushstring(L, value->c_str());
|
|
lua_pcall(L, 1 /* one arg */, 1 /* one result */, 0);
|
|
lua_pop(L, 1);
|
|
}
|
|
return menu_return::RETURN_REPAINT;
|
|
}
|
|
|
|
CLuaMenuStringinput::CLuaMenuStringinput(lua_State *_L, std::string _luaAction, std::string _luaId, const char *_name, std::string *_value, int _size, std::string _valid_chars, CChangeObserver *_observ, const char *_icon, bool _sms) : CLuaMenuForwarder(_L, _luaAction, _luaId)
|
|
{
|
|
name = _name;
|
|
value = _value;
|
|
size = _size;
|
|
valid_chars = _valid_chars;
|
|
icon = _icon;
|
|
observ = _observ;
|
|
sms = _sms;
|
|
}
|
|
|
|
int CLuaMenuStringinput::exec(CMenuTarget* /*parent*/, const std::string & /*actionKey*/)
|
|
{
|
|
CStringInput *i;
|
|
if (sms)
|
|
i = new CStringInputSMS((char *)name, value, size,
|
|
NONEXISTANT_LOCALE, NONEXISTANT_LOCALE, valid_chars.c_str(), observ, icon);
|
|
else
|
|
i = new CStringInput((char *)name, value, size,
|
|
NONEXISTANT_LOCALE, NONEXISTANT_LOCALE, valid_chars.c_str(), observ, icon);
|
|
i->exec(NULL, "");
|
|
delete i;
|
|
if (!luaAction.empty()){
|
|
lua_pushglobaltable(L);
|
|
lua_getfield(L, -1, luaAction.c_str());
|
|
lua_remove(L, -2);
|
|
lua_pushstring(L, luaId.c_str());
|
|
lua_pushstring(L, value->c_str());
|
|
lua_pcall(L, 2 /* two args */, 1 /* one result */, 0);
|
|
lua_pop(L, 2);
|
|
}
|
|
return menu_return::RETURN_REPAINT;
|
|
}
|
|
|
|
CLuaMenuKeyboardinput::CLuaMenuKeyboardinput(lua_State *_L, std::string _luaAction, std::string _luaId, const char *_name, std::string *_value, int _size, CChangeObserver *_observ, const char *_icon, std::string _help, std::string _help2) : CLuaMenuForwarder(_L, _luaAction, _luaId)
|
|
{
|
|
name = _name;
|
|
value = _value;
|
|
size = _size;
|
|
icon = _icon;
|
|
observ = _observ;
|
|
help = _help;
|
|
help2 = _help2;
|
|
}
|
|
|
|
int CLuaMenuKeyboardinput::exec(CMenuTarget* /*parent*/, const std::string & /*actionKey*/)
|
|
{
|
|
CKeyboardInput *i;
|
|
i = new CKeyboardInput((char *)name, value, size, observ, icon, help, help2);
|
|
i->exec(NULL, "");
|
|
delete i;
|
|
if (!luaAction.empty()){
|
|
lua_pushglobaltable(L);
|
|
lua_getfield(L, -1, luaAction.c_str());
|
|
lua_remove(L, -2);
|
|
lua_pushstring(L, luaId.c_str());
|
|
lua_pushstring(L, value->c_str());
|
|
lua_pcall(L, 2 /* two args */, 1 /* one result */, 0);
|
|
lua_pop(L, 2);
|
|
}
|
|
return menu_return::RETURN_REPAINT;
|
|
}
|
|
|
|
int CLuaInstance::MenuNew(lua_State *L)
|
|
{
|
|
CMenuWidget *m;
|
|
|
|
if (lua_istable(L, 1)) {
|
|
std::string name, icon;
|
|
tableLookup(L, "name", name) || tableLookup(L, "title", name);
|
|
tableLookup(L, "icon", icon);
|
|
lua_Integer mwidth;
|
|
if(tableLookup(L, "mwidth", mwidth))
|
|
m = new CMenuWidget(name.c_str(), icon.c_str(), mwidth);
|
|
else
|
|
m = new CMenuWidget(name.c_str(), icon.c_str());
|
|
} else
|
|
m = new CMenuWidget();
|
|
|
|
CLuaMenu **udata = (CLuaMenu **) lua_newuserdata(L, sizeof(CLuaMenu *));
|
|
*udata = new CLuaMenu();
|
|
(*udata)->m = m;
|
|
luaL_getmetatable(L, "menu");
|
|
lua_setmetatable(L, -2);
|
|
return 1;
|
|
}
|
|
|
|
int CLuaInstance::MenuDelete(lua_State *L)
|
|
{
|
|
CLuaMenu *m = MenuCheck(L, 1);
|
|
if (!m)
|
|
return 0;
|
|
|
|
while(!m->targets.empty()) {
|
|
delete m->targets.back();
|
|
m->targets.pop_back();
|
|
}
|
|
while(!m->tofree.empty()) {
|
|
free(m->tofree.back());
|
|
m->tofree.pop_back();
|
|
}
|
|
|
|
delete m;
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::MenuAddKey(lua_State *L)
|
|
{
|
|
CLuaMenu *m = MenuCheck(L, 1);
|
|
if (!m)
|
|
return 0;
|
|
lua_assert(lua_istable(L, 2));
|
|
|
|
std::string action; tableLookup(L, "action", action);
|
|
std::string id; tableLookup(L, "id", id);
|
|
lua_Unsigned directkey = CRCInput::RC_nokey;
|
|
tableLookup(L, "directkey", directkey);
|
|
if ((!action.empty()) && (directkey != CRCInput::RC_nokey)) {
|
|
CLuaMenuForwarder *forwarder = new CLuaMenuForwarder(L, action, id);
|
|
m->m->addKey(directkey, forwarder, action);
|
|
m->targets.push_back(forwarder);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::MenuAddItem(lua_State *L)
|
|
{
|
|
CLuaMenu *m = MenuCheck(L, 1);
|
|
if (!m)
|
|
return 0;
|
|
lua_assert(lua_istable(L, 2));
|
|
|
|
CLuaMenuItem i;
|
|
m->items.push_back(i);
|
|
CLuaMenuItem *b = &m->items.back();
|
|
|
|
tableLookup(L, "name", b->name);
|
|
std::string type; tableLookup(L, "type", type);
|
|
if (type == "back") {
|
|
m->m->addItem(GenericMenuBack);
|
|
} else if (type == "next") {
|
|
m->m->addItem(GenericMenuNext);
|
|
} else if (type == "cancel") {
|
|
m->m->addItem(GenericMenuCancel);
|
|
} else if (type == "separator") {
|
|
m->m->addItem(GenericMenuSeparator);
|
|
} else if ((type == "separatorline") || (type == "subhead")) {
|
|
if (!b->name.empty()) {
|
|
int flag = (type == "separatorline") ? CMenuSeparator::LINE : CMenuSeparator::SUB_HEAD;
|
|
m->m->addItem(new CMenuSeparator(CMenuSeparator::STRING | flag, b->name.c_str(), NONEXISTANT_LOCALE));
|
|
} else
|
|
m->m->addItem(GenericMenuSeparatorLine);
|
|
} else {
|
|
std::string right_icon_str; tableLookup(L, "right_icon", right_icon_str);
|
|
std::string action; tableLookup(L, "action", action);
|
|
std::string value; tableLookup(L, "value", value);
|
|
std::string hint; tableLookup(L, "hint", hint);
|
|
std::string hint_icon_str; tableLookup(L, "hint_icon", hint_icon_str);
|
|
std::string icon_str; tableLookup(L, "icon", icon_str);
|
|
std::string id; tableLookup(L, "id", id);
|
|
std::string tmp;
|
|
char *right_icon = NULL;
|
|
if (!right_icon_str.empty()) {
|
|
right_icon = strdup(right_icon_str.c_str());
|
|
m->tofree.push_back(right_icon);
|
|
}
|
|
char *hint_icon = NULL;
|
|
if (!hint_icon_str.empty()) {
|
|
hint_icon = strdup(hint_icon_str.c_str());
|
|
m->tofree.push_back(hint_icon);
|
|
}
|
|
char *icon = NULL;
|
|
if (!icon_str.empty()) {
|
|
icon = strdup(icon_str.c_str());
|
|
m->tofree.push_back(icon);
|
|
}
|
|
|
|
lua_Unsigned directkey = CRCInput::RC_nokey;
|
|
lua_Integer pulldown = false;
|
|
tableLookup(L, "directkey", directkey);
|
|
tableLookup(L, "pulldown", pulldown);
|
|
|
|
bool enabled = true;
|
|
if (!(tableLookup(L, "enabled", enabled) || tableLookup(L, "active", enabled)))
|
|
{
|
|
tmp = "true";
|
|
if (tableLookup(L, "enabled", tmp) || tableLookup(L, "active", tmp))
|
|
paramBoolDeprecated(L, tmp.c_str());
|
|
enabled = (tmp == "true" || tmp == "1" || tmp == "yes");
|
|
}
|
|
|
|
tableLookup(L, "range", tmp);
|
|
int range_from = 0, range_to = 99;
|
|
sscanf(tmp.c_str(), "%d,%d", &range_from, &range_to);
|
|
|
|
CMenuItem *mi = NULL;
|
|
|
|
if (type == "forwarder") {
|
|
b->str_val = value;
|
|
CLuaMenuForwarder *forwarder = new CLuaMenuForwarder(L, action, id);
|
|
mi = new CMenuForwarder(b->name, enabled, b->str_val, forwarder, NULL/*ActionKey*/, directkey, icon, right_icon);
|
|
if (!hint.empty() || hint_icon)
|
|
mi->setHint(hint_icon, hint);
|
|
m->targets.push_back(forwarder);
|
|
} else if (type == "chooser") {
|
|
int options_count = 0;
|
|
lua_pushstring(L, "options");
|
|
lua_gettable(L, -2);
|
|
if (lua_istable(L, -1))
|
|
for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 2)) {
|
|
lua_pushvalue(L, -2);
|
|
options_count++;
|
|
}
|
|
lua_pop(L, 1);
|
|
if (options_count == 0) {
|
|
m->m->addItem(new CMenuSeparator(CMenuSeparator::STRING | CMenuSeparator::LINE, "ERROR! (options_count)", NONEXISTANT_LOCALE));
|
|
return 0;
|
|
}
|
|
|
|
CMenuOptionChooser::keyval_ext *kext = (CMenuOptionChooser::keyval_ext *)calloc(options_count, sizeof(CMenuOptionChooser::keyval_ext));
|
|
m->tofree.push_back(kext);
|
|
lua_pushstring(L, "options");
|
|
lua_gettable(L, -2);
|
|
b->int_val = 0;
|
|
int j = 0;
|
|
if (lua_istable(L, -1))
|
|
for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 2)) {
|
|
lua_pushvalue(L, -2);
|
|
const char *key = lua_tostring(L, -1);
|
|
const char *val = lua_tostring(L, -2);
|
|
kext[j].key = atoi(key);
|
|
kext[j].value = NONEXISTANT_LOCALE;
|
|
kext[j].valname = strdup(val);
|
|
m->tofree.push_back((void *)kext[j].valname);
|
|
if (!strcmp(value.c_str(), kext[j].valname))
|
|
b->int_val = kext[j].key;
|
|
j++;
|
|
}
|
|
lua_pop(L, 1);
|
|
mi = new CMenuOptionChooser(b->name.c_str(), &b->int_val, kext, options_count, enabled, m->observ, directkey, icon, pulldown);
|
|
} else if (type == "numeric") {
|
|
b->int_val = range_from;
|
|
sscanf(value.c_str(), "%d", &b->int_val);
|
|
mi = new CMenuOptionNumberChooser(b->name, &b->int_val, enabled, range_from, range_to, m->observ, 0, 0, NONEXISTANT_LOCALE, pulldown);
|
|
} else if (type == "string") {
|
|
b->str_val = value;
|
|
mi = new CMenuOptionStringChooser(b->name.c_str(), &b->str_val, enabled, m->observ, directkey, icon, pulldown);
|
|
} else if (type == "stringinput") {
|
|
b->str_val = value;
|
|
std::string valid_chars = "abcdefghijklmnopqrstuvwxyz0123456789!\"§$%&/()=?-. ";
|
|
tableLookup(L, "valid_chars", valid_chars);
|
|
lua_Integer sms = 0, size = 30;
|
|
tableLookup(L, "sms", sms);
|
|
tableLookup(L, "size", size);
|
|
CLuaMenuStringinput *stringinput = new CLuaMenuStringinput(L, action, id, b->name.c_str(), &b->str_val, size, valid_chars, m->observ, icon, sms);
|
|
mi = new CMenuForwarder(b->name, enabled, b->str_val, stringinput, NULL/*ActionKey*/, directkey, icon, right_icon);
|
|
m->targets.push_back(stringinput);
|
|
} else if (type == "keyboardinput") {
|
|
b->str_val = value;
|
|
lua_Integer size = 0; tableLookup(L, "size", size);
|
|
std::string help = ""; tableLookup(L, "help", help);
|
|
std::string help2 = ""; tableLookup(L, "help2", help2);
|
|
CLuaMenuKeyboardinput *keyboardinput = new CLuaMenuKeyboardinput(L, action, id, b->name.c_str(), &b->str_val, size, m->observ, icon, help, help2);
|
|
mi = new CMenuForwarder(b->name, enabled, b->str_val, keyboardinput, NULL/*ActionKey*/, directkey, icon, right_icon);
|
|
m->targets.push_back(keyboardinput);
|
|
} else if (type == "filebrowser") {
|
|
b->str_val = value;
|
|
lua_Integer dirMode = 0;
|
|
tableLookup(L, "dir_mode", dirMode);
|
|
CLuaMenuFilebrowser *filebrowser = new CLuaMenuFilebrowser(L, action, id, &b->str_val, dirMode);
|
|
lua_pushstring(L, "filter");
|
|
lua_gettable(L, -2);
|
|
if (lua_istable(L, -1))
|
|
for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 2)) {
|
|
lua_pushvalue(L, -2);
|
|
const char *val = lua_tostring(L, -2);
|
|
filebrowser->addFilter(val);
|
|
}
|
|
lua_pop(L, 1);
|
|
|
|
mi = new CMenuForwarder(b->name, enabled, b->str_val, filebrowser, NULL/*ActionKey*/, directkey, icon, right_icon);
|
|
m->targets.push_back(filebrowser);
|
|
}
|
|
if (mi) {
|
|
mi->setLua(L, action, id);
|
|
if (!hint.empty() || hint_icon)
|
|
mi->setHint(hint_icon, hint);
|
|
m->m->addItem(mi);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::MenuHide(lua_State *L)
|
|
{
|
|
CLuaMenu *m = MenuCheck(L, 1);
|
|
if (!m)
|
|
return 0;
|
|
m->m->hide();
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::MenuExec(lua_State *L)
|
|
{
|
|
CLuaMenu *m = MenuCheck(L, 1);
|
|
if (!m)
|
|
return 0;
|
|
m->m->exec(NULL, "");
|
|
m->m->hide();
|
|
return 0;
|
|
}
|
|
|
|
void CLuaInstance::HintboxRegister(lua_State *L)
|
|
{
|
|
luaL_Reg meth[] = {
|
|
{ "new", CLuaInstance::HintboxNew },
|
|
{ "exec", CLuaInstance::HintboxExec },
|
|
{ "paint", CLuaInstance::HintboxPaint },
|
|
{ "hide", CLuaInstance::HintboxHide },
|
|
{ "__gc", CLuaInstance::HintboxDelete },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
luaL_newmetatable(L, "hintbox");
|
|
luaL_setfuncs(L, meth, 0);
|
|
lua_pushvalue(L, -1);
|
|
lua_setfield(L, -1, "__index");
|
|
lua_setglobal(L, "hintbox");
|
|
}
|
|
|
|
CLuaHintbox *CLuaInstance::HintboxCheck(lua_State *L, int n)
|
|
{
|
|
return *(CLuaHintbox **) luaL_checkudata(L, n, "hintbox");
|
|
}
|
|
|
|
CLuaHintbox::CLuaHintbox()
|
|
{
|
|
caption = NULL;
|
|
b = NULL;
|
|
}
|
|
|
|
CLuaHintbox::~CLuaHintbox()
|
|
{
|
|
if (caption)
|
|
free(caption);
|
|
delete b;
|
|
}
|
|
|
|
int CLuaInstance::HintboxNew(lua_State *L)
|
|
{
|
|
lua_assert(lua_istable(L,1));
|
|
|
|
std::string name, text, icon = std::string(NEUTRINO_ICON_INFO);
|
|
tableLookup(L, "name", name) || tableLookup(L, "title", name) || tableLookup(L, "caption", name);
|
|
tableLookup(L, "text", text);
|
|
tableLookup(L, "icon", icon);
|
|
lua_Integer width = 450;
|
|
tableLookup(L, "width", width);
|
|
|
|
CLuaHintbox **udata = (CLuaHintbox **) lua_newuserdata(L, sizeof(CLuaHintbox *));
|
|
*udata = new CLuaHintbox();
|
|
(*udata)->caption = strdup(name.c_str());
|
|
(*udata)->b = new CHintBox((*udata)->caption, text.c_str(), width, icon.c_str());
|
|
luaL_getmetatable(L, "hintbox");
|
|
lua_setmetatable(L, -2);
|
|
return 1;
|
|
}
|
|
|
|
int CLuaInstance::HintboxDelete(lua_State *L)
|
|
{
|
|
CLuaHintbox *m = HintboxCheck(L, 1);
|
|
delete m;
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::HintboxPaint(lua_State *L)
|
|
{
|
|
CLuaHintbox *m = HintboxCheck(L, 1);
|
|
if (!m)
|
|
return 0;
|
|
m->b->paint();
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::HintboxHide(lua_State *L)
|
|
{
|
|
CLuaHintbox *m = HintboxCheck(L, 1);
|
|
m->b->hide();
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::HintboxExec(lua_State *L)
|
|
{
|
|
CLuaHintbox *m = HintboxCheck(L, 1);
|
|
if (!m)
|
|
return 0;
|
|
int timeout = -1;
|
|
if (lua_isnumber(L, -1))
|
|
timeout = (int) lua_tonumber(L, -1);
|
|
m->b->paint();
|
|
|
|
// copied from gui/widget/hintbox.cpp
|
|
|
|
neutrino_msg_t msg;
|
|
neutrino_msg_data_t data;
|
|
if ( timeout == -1 )
|
|
timeout = 5; /// default timeout 5 sec
|
|
//timeout = g_settings.timing[SNeutrinoSettings::TIMING_INFOBAR];
|
|
|
|
uint64_t timeoutEnd = CRCInput::calcTimeoutEnd( timeout );
|
|
|
|
int res = messages_return::none;
|
|
|
|
while ( ! ( res & ( messages_return::cancel_info | messages_return::cancel_all ) ) )
|
|
{
|
|
g_RCInput->getMsgAbsoluteTimeout( &msg, &data, &timeoutEnd );
|
|
|
|
if ((msg == CRCInput::RC_timeout) || (msg == CRCInput::RC_ok))
|
|
res = messages_return::cancel_info;
|
|
else if(msg == CRCInput::RC_home)
|
|
res = messages_return::cancel_all;
|
|
else if ((m->b->has_scrollbar()) && ((msg == CRCInput::RC_up) || (msg == CRCInput::RC_down)))
|
|
{
|
|
if (msg == CRCInput::RC_up)
|
|
m->b->scroll_up();
|
|
else
|
|
m->b->scroll_down();
|
|
}
|
|
else if((msg == CRCInput::RC_sat) || (msg == CRCInput::RC_favorites)) {
|
|
}
|
|
else if(msg == CRCInput::RC_mode) {
|
|
res = messages_return::handled;
|
|
break;
|
|
}
|
|
else if((msg == CRCInput::RC_next) || (msg == CRCInput::RC_prev)) {
|
|
res = messages_return::cancel_all;
|
|
g_RCInput->postMsg(msg, data);
|
|
}
|
|
else
|
|
{
|
|
res = CNeutrinoApp::getInstance()->handleMsg(msg, data);
|
|
if (res & messages_return::unhandled)
|
|
{
|
|
|
|
// leave here and handle above...
|
|
g_RCInput->postMsg(msg, data);
|
|
res = messages_return::cancel_all;
|
|
}
|
|
}
|
|
}
|
|
m->b->hide();
|
|
return 0;
|
|
}
|
|
|
|
void CLuaInstance::MessageboxRegister(lua_State *L)
|
|
{
|
|
luaL_Reg meth[] = {
|
|
{ "exec", CLuaInstance::MessageboxExec },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
luaL_newmetatable(L, "messagebox");
|
|
luaL_setfuncs(L, meth, 0);
|
|
lua_pushvalue(L, -1);
|
|
lua_setfield(L, -1, "__index");
|
|
lua_setglobal(L, "messagebox");
|
|
}
|
|
|
|
// messagebox.exec{caption="Title", text="text", icon="settings", width=500,timeout=-1,return_default_on_timeout=0,
|
|
// default = "yes", buttons = { "yes", "no", "cancel", "all", "back", "ok" }, align="center1|center2|left|right" }
|
|
int CLuaInstance::MessageboxExec(lua_State *L)
|
|
{
|
|
lua_assert(lua_istable(L,1));
|
|
|
|
std::string name, text, icon = std::string(NEUTRINO_ICON_INFO);
|
|
tableLookup(L, "name", name) || tableLookup(L, "title", name) || tableLookup(L, "caption", name);
|
|
tableLookup(L, "text", text);
|
|
tableLookup(L, "icon", icon);
|
|
lua_Integer timeout = -1, width = 450, return_default_on_timeout = 0;
|
|
int show_buttons = 0, default_button = 0;
|
|
tableLookup(L, "timeout", timeout);
|
|
tableLookup(L, "width", width);
|
|
tableLookup(L, "return_default_on_timeout", return_default_on_timeout);
|
|
|
|
std::string tmp;
|
|
if (tableLookup(L, "align", tmp)) {
|
|
lua_pushvalue(L, -2);
|
|
const char *val = lua_tostring(L, -2);
|
|
table_key mb[] = {
|
|
{ "center1", CMessageBox::mbBtnAlignCenter1 },
|
|
{ "center2", CMessageBox::mbBtnAlignCenter2 },
|
|
{ "left", CMessageBox::mbBtnAlignLeft },
|
|
{ "right", CMessageBox::mbBtnAlignRight },
|
|
{ NULL, 0 }
|
|
};
|
|
for (int i = 0; mb[i].name; i++)
|
|
if (!strcmp(mb[i].name, val)) {
|
|
show_buttons |= mb[i].code;
|
|
break;
|
|
}
|
|
}
|
|
lua_pushstring(L, "buttons");
|
|
lua_gettable(L, -2);
|
|
for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 2)) {
|
|
lua_pushvalue(L, -2);
|
|
const char *val = lua_tostring(L, -2);
|
|
table_key mb[] = {
|
|
{ "yes", CMessageBox::mbYes },
|
|
{ "no", CMessageBox::mbNo },
|
|
{ "cancel", CMessageBox::mbCancel },
|
|
{ "all", CMessageBox::mbAll },
|
|
{ "back", CMessageBox::mbBack },
|
|
{ "ok", CMessageBox::mbOk },
|
|
{ NULL, 0 }
|
|
};
|
|
for (int i = 0; mb[i].name; i++)
|
|
if (!strcmp(mb[i].name, val)) {
|
|
show_buttons |= mb[i].code;
|
|
break;
|
|
}
|
|
}
|
|
lua_pop(L, 1);
|
|
|
|
table_key mbr[] = {
|
|
{ "yes", CMessageBox::mbrYes },
|
|
{ "no", CMessageBox::mbrNo },
|
|
{ "cancel", CMessageBox::mbrCancel },
|
|
{ "back", CMessageBox::mbrBack },
|
|
{ "ok", CMessageBox::mbrOk },
|
|
{ NULL, 0 }
|
|
};
|
|
if (tableLookup(L, "default", tmp)) {
|
|
lua_pushvalue(L, -2);
|
|
const char *val = lua_tostring(L, -2);
|
|
for (int i = 0; mbr[i].name; i++)
|
|
if (!strcmp(mbr[i].name, val)) {
|
|
default_button = mbr[i].code;
|
|
break;
|
|
}
|
|
}
|
|
|
|
int res = ShowMsg(name, text, (CMessageBox::result_) default_button, (CMessageBox::buttons_) show_buttons, icon.empty() ? NULL : icon.c_str(), width, timeout, return_default_on_timeout);
|
|
|
|
tmp = "cancel";
|
|
for (int i = 0; mbr[i].name; i++)
|
|
if (res == mbr[i].code) {
|
|
tmp = mbr[i].name;
|
|
break;
|
|
}
|
|
lua_pushstring(L, tmp.c_str());
|
|
|
|
return 1;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|
|
|
|
void CLuaInstance::CWindowRegister(lua_State *L)
|
|
{
|
|
luaL_Reg meth[] = {
|
|
{ "new", CLuaInstance::CWindowNew },
|
|
{ "paint", CLuaInstance::CWindowPaint },
|
|
{ "hide", CLuaInstance::CWindowHide },
|
|
{ "setCaption", CLuaInstance::CWindowSetCaption },
|
|
{ "setWindowColor", CLuaInstance::CWindowSetWindowColor },
|
|
{ "paintHeader", CLuaInstance::CWindowPaintHeader },
|
|
{ "headerHeight", CLuaInstance::CWindowGetHeaderHeight },
|
|
{ "footerHeight", CLuaInstance::CWindowGetFooterHeight },
|
|
{ "header_height", CLuaInstance::CWindowGetHeaderHeight_dep }, /* function 'header_height' is deprecated */
|
|
{ "footer_height", CLuaInstance::CWindowGetFooterHeight_dep }, /* function 'footer_height' is deprecated */
|
|
{ "__gc", CLuaInstance::CWindowDelete },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
luaL_newmetatable(L, "cwindow");
|
|
luaL_setfuncs(L, meth, 0);
|
|
lua_pushvalue(L, -1);
|
|
lua_setfield(L, -1, "__index");
|
|
lua_setglobal(L, "cwindow");
|
|
}
|
|
|
|
int CLuaInstance::CWindowNew(lua_State *L)
|
|
{
|
|
lua_assert(lua_istable(L,1));
|
|
|
|
std::string name, icon = std::string(NEUTRINO_ICON_INFO);
|
|
lua_Unsigned color_frame = (lua_Unsigned)COL_MENUCONTENT_PLUS_6;
|
|
lua_Unsigned color_body = (lua_Unsigned)COL_MENUCONTENT_PLUS_0;
|
|
lua_Unsigned color_shadow = (lua_Unsigned)COL_MENUCONTENTDARK_PLUS_0;
|
|
std::string tmp1 = "false";
|
|
std::string btnRed = "";
|
|
std::string btnGreen = "";
|
|
std::string btnYellow = "";
|
|
std::string btnBlue = "";
|
|
lua_Integer x = 100, y = 100, dx = 450, dy = 250;
|
|
tableLookup(L, "x", x);
|
|
tableLookup(L, "y", y);
|
|
tableLookup(L, "dx", dx);
|
|
tableLookup(L, "dy", dy);
|
|
tableLookup(L, "name", name) || tableLookup(L, "title", name) || tableLookup(L, "caption", name);
|
|
tableLookup(L, "icon", icon);
|
|
|
|
bool has_shadow = false;
|
|
if (!tableLookup(L, "has_shadow", has_shadow))
|
|
{
|
|
tmp1 = "false";
|
|
if (tableLookup(L, "has_shadow", tmp1))
|
|
paramBoolDeprecated(L, tmp1.c_str());
|
|
has_shadow = (tmp1 == "true" || tmp1 == "1" || tmp1 == "yes");
|
|
}
|
|
|
|
tableLookup(L, "color_frame" , color_frame);
|
|
tableLookup(L, "color_body" , color_body);
|
|
tableLookup(L, "color_shadow", color_shadow);
|
|
tableLookup(L, "btnRed", btnRed);
|
|
tableLookup(L, "btnGreen", btnGreen);
|
|
tableLookup(L, "btnYellow", btnYellow);
|
|
tableLookup(L, "btnBlue", btnBlue);
|
|
|
|
checkMagicMask(color_frame);
|
|
checkMagicMask(color_body);
|
|
checkMagicMask(color_shadow);
|
|
|
|
bool show_header = true;
|
|
if (!tableLookup(L, "show_header", show_header))
|
|
{
|
|
tmp1 = "true";
|
|
if (tableLookup(L, "show_header", tmp1))
|
|
paramBoolDeprecated(L, tmp1.c_str());
|
|
show_header = (tmp1 == "true" || tmp1 == "1" || tmp1 == "yes");
|
|
}
|
|
bool show_footer = true;
|
|
if (!tableLookup(L, "show_footer", show_footer))
|
|
{
|
|
tmp1 = "true";
|
|
if (tableLookup(L, "show_footer", tmp1))
|
|
paramBoolDeprecated(L, tmp1.c_str());
|
|
show_footer = (tmp1 == "true" || tmp1 == "1" || tmp1 == "yes");
|
|
}
|
|
|
|
CLuaCWindow **udata = (CLuaCWindow **) lua_newuserdata(L, sizeof(CLuaCWindow *));
|
|
*udata = new CLuaCWindow();
|
|
(*udata)->w = new CComponentsWindow(x, y, dx, dy, name.c_str(), icon.c_str(), 0, has_shadow, (fb_pixel_t)color_frame, (fb_pixel_t)color_body, (fb_pixel_t)color_shadow);
|
|
|
|
if (!show_header)
|
|
(*udata)->w->showHeader(false);
|
|
if (!show_footer)
|
|
(*udata)->w->showFooter(false);
|
|
else {
|
|
CComponentsFooter* footer = (*udata)->w->getFooterObject();
|
|
if (footer) {
|
|
vector<button_label_s> buttons;
|
|
if (!btnRed.empty()){
|
|
button_label_s btnSred;
|
|
btnSred.button = NEUTRINO_ICON_BUTTON_RED;
|
|
btnSred.text = btnRed;
|
|
buttons.push_back(btnSred);
|
|
}
|
|
if (!btnGreen.empty()){
|
|
button_label_s btnSgreen;
|
|
btnSgreen.button = NEUTRINO_ICON_BUTTON_GREEN;
|
|
btnSgreen.text = btnGreen;
|
|
buttons.push_back(btnSgreen);
|
|
}
|
|
if (!btnYellow.empty()){
|
|
button_label_s btnSyellow;
|
|
btnSyellow.button = NEUTRINO_ICON_BUTTON_YELLOW;
|
|
btnSyellow.text = btnYellow;
|
|
buttons.push_back(btnSyellow);
|
|
}
|
|
if (!btnBlue.empty()){
|
|
button_label_s btnSblue;
|
|
btnSblue.button = NEUTRINO_ICON_BUTTON_YELLOW;
|
|
btnSblue.text = btnBlue;
|
|
buttons.push_back(btnSblue);
|
|
}
|
|
if(!buttons.empty())
|
|
footer->setButtonLabels(buttons, dx-20, (dx-20) / (buttons.size()+1));
|
|
}
|
|
}
|
|
|
|
luaL_getmetatable(L, "cwindow");
|
|
lua_setmetatable(L, -2);
|
|
return 1;
|
|
}
|
|
|
|
CLuaCWindow *CLuaInstance::CWindowCheck(lua_State *L, int n)
|
|
{
|
|
return *(CLuaCWindow **) luaL_checkudata(L, n, "cwindow");
|
|
}
|
|
|
|
int CLuaInstance::CWindowPaint(lua_State *L)
|
|
{
|
|
lua_assert(lua_istable(L,1));
|
|
CLuaCWindow *m = CWindowCheck(L, 1);
|
|
if (!m) return 0;
|
|
|
|
bool do_save_bg = true;
|
|
if (!tableLookup(L, "do_save_bg", do_save_bg))
|
|
{
|
|
std::string tmp = "true";
|
|
if (tableLookup(L, "do_save_bg", tmp))
|
|
paramBoolDeprecated(L, tmp.c_str());
|
|
do_save_bg = (tmp == "true" || tmp == "1" || tmp == "yes");
|
|
}
|
|
m->w->paint(do_save_bg);
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::CWindowHide(lua_State *L)
|
|
{
|
|
lua_assert(lua_istable(L,1));
|
|
CLuaCWindow *m = CWindowCheck(L, 1);
|
|
if (!m) return 0;
|
|
|
|
bool no_restore = false;
|
|
if (!tableLookup(L, "no_restore", no_restore))
|
|
{
|
|
std::string tmp = "false";
|
|
if (tableLookup(L, "no_restore", tmp))
|
|
paramBoolDeprecated(L, tmp.c_str());
|
|
no_restore = (tmp == "true" || tmp == "1" || tmp == "yes");
|
|
}
|
|
m->w->hide(no_restore);
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::CWindowSetCaption(lua_State *L)
|
|
{
|
|
lua_assert(lua_istable(L,1));
|
|
CLuaCWindow *m = CWindowCheck(L, 1);
|
|
if (!m) return 0;
|
|
|
|
std::string name = "";
|
|
tableLookup(L, "name", name) || tableLookup(L, "title", name) || tableLookup(L, "caption", name);
|
|
|
|
m->w->setWindowCaption(name);
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::CWindowSetWindowColor(lua_State *L)
|
|
{
|
|
lua_assert(lua_istable(L,1));
|
|
CLuaCWindow *m = CWindowCheck(L, 1);
|
|
if (!m) return 0;
|
|
|
|
lua_Unsigned color;
|
|
if (tableLookup(L, "color_frame" , color)) {
|
|
checkMagicMask(color);
|
|
m->w->setColorFrame(color);
|
|
}
|
|
if (tableLookup(L, "color_body" , color)) {
|
|
checkMagicMask(color);
|
|
m->w->setColorBody(color);
|
|
}
|
|
if (tableLookup(L, "color_shadow" , color)) {
|
|
checkMagicMask(color);
|
|
m->w->setColorShadow(color);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::CWindowPaintHeader(lua_State *L)
|
|
{
|
|
CLuaCWindow *m = CWindowCheck(L, 1);
|
|
if (!m) return 0;
|
|
|
|
CComponentsHeader* header = m->w->getHeaderObject();
|
|
if (header)
|
|
m->w->showHeader();
|
|
header->paint();
|
|
|
|
return 0;
|
|
}
|
|
|
|
// function 'header_height' is deprecated
|
|
int CLuaInstance::CWindowGetHeaderHeight_dep(lua_State *L)
|
|
{
|
|
functionDeprecated(L, "header_height", "headerHeight");
|
|
return CWindowGetHeaderHeight(L);
|
|
}
|
|
|
|
// function 'footer_height' is deprecated
|
|
int CLuaInstance::CWindowGetFooterHeight_dep(lua_State *L)
|
|
{
|
|
functionDeprecated(L, "footer_height", "footerHeight");
|
|
return CWindowGetFooterHeight(L);
|
|
}
|
|
|
|
int CLuaInstance::CWindowGetHeaderHeight(lua_State *L)
|
|
{
|
|
CLuaCWindow *m = CWindowCheck(L, 1);
|
|
if (!m)
|
|
return 0;
|
|
|
|
CComponentsHeader* header = m->w->getHeaderObject();
|
|
int hh = 0;
|
|
if (header)
|
|
hh = header->getHeight();
|
|
lua_pushinteger(L, hh);
|
|
return 1;
|
|
}
|
|
|
|
int CLuaInstance::CWindowGetFooterHeight(lua_State *L)
|
|
{
|
|
CLuaCWindow *m = CWindowCheck(L, 1);
|
|
if (!m)
|
|
return 0;
|
|
|
|
CComponentsFooter* footer = m->w->getFooterObject();
|
|
int fh = 0;
|
|
if (footer)
|
|
fh = footer->getHeight();
|
|
lua_pushinteger(L, fh);
|
|
return 1;
|
|
}
|
|
|
|
int CLuaInstance::CWindowDelete(lua_State *L)
|
|
{
|
|
DBG("CLuaInstance::%s %d\n", __func__, lua_gettop(L));
|
|
CLuaCWindow *m = CWindowCheck(L, 1);
|
|
if (!m)
|
|
return 0;
|
|
|
|
delete m;
|
|
return 0;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|
|
|
|
CLuaSignalBox *CLuaInstance::SignalBoxCheck(lua_State *L, int n)
|
|
{
|
|
return *(CLuaSignalBox **) luaL_checkudata(L, n, "signalbox");
|
|
}
|
|
|
|
void CLuaInstance::SignalBoxRegister(lua_State *L)
|
|
{
|
|
luaL_Reg meth[] = {
|
|
{ "new", CLuaInstance::SignalBoxNew },
|
|
{ "paint", CLuaInstance::SignalBoxPaint },
|
|
{ "__gc", CLuaInstance::SignalBoxDelete },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
luaL_newmetatable(L, "signalbox");
|
|
luaL_setfuncs(L, meth, 0);
|
|
lua_pushvalue(L, -1);
|
|
lua_setfield(L, -1, "__index");
|
|
lua_setglobal(L, "signalbox");
|
|
}
|
|
|
|
int CLuaInstance::SignalBoxNew(lua_State *L)
|
|
{
|
|
lua_assert(lua_istable(L,1));
|
|
|
|
std::string name, icon = std::string(NEUTRINO_ICON_INFO);
|
|
lua_Integer x = 110, y = 150, dx = 430, dy = 150;
|
|
lua_Integer vertical = true;
|
|
CLuaCWindow* parent = NULL;
|
|
tableLookup(L, "x", x);
|
|
tableLookup(L, "y", y);
|
|
tableLookup(L, "dx", dx);
|
|
tableLookup(L, "dy", dy);
|
|
tableLookup(L, "vertical", vertical);
|
|
tableLookup(L, "parent", (void**)&parent);
|
|
|
|
CComponentsForm* pw = (parent && parent->w) ? parent->w->getBodyObject() : NULL;
|
|
CLuaSignalBox **udata = (CLuaSignalBox **) lua_newuserdata(L, sizeof(CLuaSignalBox *));
|
|
*udata = new CLuaSignalBox();
|
|
(*udata)->s = new CSignalBox(x, y, dx, dy, NULL, (vertical!=0)?true:false, pw);
|
|
(*udata)->parent = pw;
|
|
luaL_getmetatable(L, "signalbox");
|
|
lua_setmetatable(L, -2);
|
|
return 1;
|
|
}
|
|
|
|
int CLuaInstance::SignalBoxPaint(lua_State *L)
|
|
{
|
|
lua_assert(lua_istable(L,1));
|
|
CLuaSignalBox *m = SignalBoxCheck(L, 1);
|
|
if (!m) return 0;
|
|
|
|
bool do_save_bg = true;
|
|
if (!tableLookup(L, "do_save_bg", do_save_bg))
|
|
{
|
|
std::string tmp = "true";
|
|
if (tableLookup(L, "do_save_bg", tmp))
|
|
paramBoolDeprecated(L, tmp.c_str());
|
|
do_save_bg = (tmp == "true" || tmp == "1" || tmp == "yes");
|
|
}
|
|
m->s->paint(do_save_bg);
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::SignalBoxDelete(lua_State *L)
|
|
{
|
|
CLuaSignalBox *m = SignalBoxCheck(L, 1);
|
|
if (!m)
|
|
return 0;
|
|
|
|
delete m;
|
|
return 0;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|
|
|
|
CLuaComponentsText *CLuaInstance::ComponentsTextCheck(lua_State *L, int n)
|
|
{
|
|
return *(CLuaComponentsText **) luaL_checkudata(L, n, "ctext");
|
|
}
|
|
|
|
void CLuaInstance::ComponentsTextRegister(lua_State *L)
|
|
{
|
|
luaL_Reg meth[] = {
|
|
{ "new", CLuaInstance::ComponentsTextNew },
|
|
{ "paint", CLuaInstance::ComponentsTextPaint },
|
|
{ "hide", CLuaInstance::ComponentsTextHide },
|
|
{ "setText", CLuaInstance::ComponentsTextSetText },
|
|
{ "scroll", CLuaInstance::ComponentsTextScroll },
|
|
{ "__gc", CLuaInstance::ComponentsTextDelete },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
luaL_newmetatable(L, "ctext");
|
|
luaL_setfuncs(L, meth, 0);
|
|
lua_pushvalue(L, -1);
|
|
lua_setfield(L, -1, "__index");
|
|
lua_setglobal(L, "ctext");
|
|
}
|
|
|
|
int CLuaInstance::ComponentsTextNew(lua_State *L)
|
|
{
|
|
lua_assert(lua_istable(L,1));
|
|
|
|
CLuaCWindow* parent = NULL;
|
|
lua_Integer x = 10, y = 10, dx = 100, dy = 100;
|
|
std::string text = "";
|
|
std::string tmpMode = "";
|
|
int mode = CTextBox::AUTO_WIDTH;
|
|
lua_Integer font_text = SNeutrinoSettings::FONT_TYPE_MENU;
|
|
lua_Unsigned color_text = (lua_Unsigned)COL_MENUCONTENT_TEXT;
|
|
lua_Unsigned color_frame = (lua_Unsigned)COL_MENUCONTENT_PLUS_6;
|
|
lua_Unsigned color_body = (lua_Unsigned)COL_MENUCONTENT_PLUS_0;
|
|
lua_Unsigned color_shadow = (lua_Unsigned)COL_MENUCONTENTDARK_PLUS_0;
|
|
|
|
tableLookup(L, "parent" , (void**)&parent);
|
|
tableLookup(L, "x" , x);
|
|
tableLookup(L, "y" , y);
|
|
tableLookup(L, "dx" , dx);
|
|
tableLookup(L, "dy" , dy);
|
|
tableLookup(L, "text" , text);
|
|
tableLookup(L, "mode" , tmpMode);
|
|
tableLookup(L, "font_text" , font_text);
|
|
if (font_text >= SNeutrinoSettings::FONT_TYPE_COUNT || font_text < 0)
|
|
font_text = SNeutrinoSettings::FONT_TYPE_MENU;
|
|
|
|
bool has_shadow = false;
|
|
if (!tableLookup(L, "has_shadow", has_shadow))
|
|
{
|
|
std::string tmp1 = "false";
|
|
if (tableLookup(L, "has_shadow", tmp1))
|
|
paramBoolDeprecated(L, tmp1.c_str());
|
|
has_shadow = (tmp1 == "true" || tmp1 == "1" || tmp1 == "yes");
|
|
}
|
|
|
|
tableLookup(L, "color_text" , color_text);
|
|
tableLookup(L, "color_frame" , color_frame);
|
|
tableLookup(L, "color_body" , color_body);
|
|
tableLookup(L, "color_shadow", color_shadow);
|
|
|
|
checkMagicMask(color_text);
|
|
checkMagicMask(color_frame);
|
|
checkMagicMask(color_body);
|
|
checkMagicMask(color_shadow);
|
|
|
|
if (!tmpMode.empty()) {
|
|
table_key txt_align[] = {
|
|
{ "ALIGN_AUTO_WIDTH", CTextBox::AUTO_WIDTH },
|
|
{ "ALIGN_AUTO_HIGH", CTextBox::AUTO_HIGH },
|
|
{ "ALIGN_SCROLL", CTextBox::SCROLL },
|
|
{ "ALIGN_CENTER", CTextBox::CENTER },
|
|
{ "ALIGN_RIGHT", CTextBox::RIGHT },
|
|
{ "ALIGN_TOP", CTextBox::TOP },
|
|
{ "ALIGN_BOTTOM", CTextBox::BOTTOM },
|
|
{ "ALIGN_NO_AUTO_LINEBREAK", CTextBox::NO_AUTO_LINEBREAK },
|
|
{ "DECODE_HTML", 0 },
|
|
{ NULL, 0 }
|
|
};
|
|
mode = 0;
|
|
for (int i = 0; txt_align[i].name; i++) {
|
|
if (tmpMode.find(txt_align[i].name) != std::string::npos)
|
|
mode |= txt_align[i].code;
|
|
}
|
|
if (tmpMode.find("DECODE_HTML") != std::string::npos)
|
|
htmlEntityDecode(text);
|
|
}
|
|
|
|
CComponentsForm* pw = (parent && parent->w) ? parent->w->getBodyObject() : NULL;
|
|
|
|
CLuaComponentsText **udata = (CLuaComponentsText **) lua_newuserdata(L, sizeof(CLuaComponentsText *));
|
|
*udata = new CLuaComponentsText();
|
|
(*udata)->ct = new CComponentsText(x, y, dx, dy, text, mode, g_Font[font_text], pw, has_shadow, (fb_pixel_t)color_text, (fb_pixel_t)color_frame, (fb_pixel_t)color_body, (fb_pixel_t)color_shadow);
|
|
(*udata)->parent = pw;
|
|
(*udata)->mode = mode;
|
|
(*udata)->font_text = font_text;
|
|
luaL_getmetatable(L, "ctext");
|
|
lua_setmetatable(L, -2);
|
|
return 1;
|
|
}
|
|
|
|
int CLuaInstance::ComponentsTextPaint(lua_State *L)
|
|
{
|
|
lua_assert(lua_istable(L,1));
|
|
CLuaComponentsText *m = ComponentsTextCheck(L, 1);
|
|
if (!m) return 0;
|
|
|
|
bool do_save_bg = true;
|
|
if (!tableLookup(L, "do_save_bg", do_save_bg))
|
|
{
|
|
std::string tmp = "true";
|
|
if (tableLookup(L, "do_save_bg", tmp))
|
|
paramBoolDeprecated(L, tmp.c_str());
|
|
do_save_bg = (tmp == "true" || tmp == "1" || tmp == "yes");
|
|
}
|
|
m->ct->paint(do_save_bg);
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::ComponentsTextHide(lua_State *L)
|
|
{
|
|
lua_assert(lua_istable(L,1));
|
|
CLuaComponentsText *m = ComponentsTextCheck(L, 1);
|
|
if (!m) return 0;
|
|
|
|
bool no_restore = false;
|
|
if (!tableLookup(L, "no_restore", no_restore))
|
|
{
|
|
std::string tmp = "false";
|
|
if (tableLookup(L, "no_restore", tmp))
|
|
paramBoolDeprecated(L, tmp.c_str());
|
|
no_restore = (tmp == "true" || tmp == "1" || tmp == "yes");
|
|
}
|
|
if (m->parent) {
|
|
m->ct->setText("", m->mode, g_Font[m->font_text]);
|
|
m->ct->paint();
|
|
} else
|
|
m->ct->hide(no_restore);
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::ComponentsTextSetText(lua_State *L)
|
|
{
|
|
lua_assert(lua_istable(L,1));
|
|
CLuaComponentsText *m = ComponentsTextCheck(L, 1);
|
|
if (!m) return 0;
|
|
|
|
std::string text = "";
|
|
lua_Integer mode = m->mode;
|
|
lua_Integer font_text = m->font_text;
|
|
tableLookup(L, "text", text);
|
|
tableLookup(L, "mode", mode);
|
|
tableLookup(L, "font_text", font_text);
|
|
|
|
m->ct->setText(text, mode, g_Font[font_text]);
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::ComponentsTextScroll(lua_State *L)
|
|
{
|
|
lua_assert(lua_istable(L,1));
|
|
CLuaComponentsText *m = ComponentsTextCheck(L, 1);
|
|
if (!m) return 0;
|
|
|
|
std::string tmp = "true";
|
|
tableLookup(L, "dir", tmp);
|
|
bool scrollDown = (tmp == "down" || tmp == "1");
|
|
|
|
//get the textbox instance from lua object and use CTexBbox scroll methods
|
|
CTextBox* ctb = m->ct->getCTextBoxObject();
|
|
if (ctb) {
|
|
ctb->enableBackgroundPaint(true);
|
|
if (scrollDown)
|
|
ctb->scrollPageDown(1);
|
|
else
|
|
ctb->scrollPageUp(1);
|
|
ctb->enableBackgroundPaint(false);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::ComponentsTextDelete(lua_State *L)
|
|
{
|
|
DBG("CLuaInstance::%s %d\n", __func__, lua_gettop(L));
|
|
CLuaComponentsText *m = ComponentsTextCheck(L, 1);
|
|
if (!m)
|
|
return 0;
|
|
|
|
delete m;
|
|
return 0;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|
|
|
|
CLuaPicture *CLuaInstance::CPictureCheck(lua_State *L, int n)
|
|
{
|
|
return *(CLuaPicture **) luaL_checkudata(L, n, "cpicture");
|
|
}
|
|
|
|
void CLuaInstance::CPictureRegister(lua_State *L)
|
|
{
|
|
luaL_Reg meth[] = {
|
|
{ "new", CLuaInstance::CPictureNew },
|
|
{ "paint", CLuaInstance::CPicturePaint },
|
|
{ "hide", CLuaInstance::CPictureHide },
|
|
{ "setPicture", CLuaInstance::CPictureSetPicture },
|
|
{ "__gc", CLuaInstance::CPictureDelete },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
luaL_newmetatable(L, "cpicture");
|
|
luaL_setfuncs(L, meth, 0);
|
|
lua_pushvalue(L, -1);
|
|
lua_setfield(L, -1, "__index");
|
|
lua_setglobal(L, "cpicture");
|
|
}
|
|
|
|
int CLuaInstance::CPictureNew(lua_State *L)
|
|
{
|
|
lua_assert(lua_istable(L,1));
|
|
|
|
CLuaCWindow* parent = NULL;
|
|
lua_Integer x=10, y=10, dx=100, dy=100;
|
|
std::string image_name = "";
|
|
lua_Integer alignment = 0;
|
|
lua_Unsigned color_frame = (lua_Unsigned)COL_MENUCONTENT_PLUS_6;
|
|
lua_Unsigned color_background = (lua_Unsigned)COL_MENUCONTENT_PLUS_0;
|
|
lua_Unsigned color_shadow = (lua_Unsigned)COL_MENUCONTENTDARK_PLUS_0;
|
|
|
|
/*
|
|
transparency = CFrameBuffer::TM_BLACK (2): Transparency when black content ('pseudo' transparency)
|
|
transparency = CFrameBuffer::TM_NONE (1): No 'pseudo' transparency
|
|
*/
|
|
lua_Integer transparency = CFrameBuffer::TM_NONE;
|
|
|
|
tableLookup(L, "parent" , (void**)&parent);
|
|
tableLookup(L, "x" , x);
|
|
tableLookup(L, "y" , y);
|
|
tableLookup(L, "dx" , dx);
|
|
tableLookup(L, "dy" , dy);
|
|
tableLookup(L, "image" , image_name);
|
|
|
|
tableLookup(L, "alignment" , alignment); //invalid argumet, for compatibility
|
|
if (alignment)
|
|
dprintf(DEBUG_NORMAL, "[CLuaInstance][%s - %d] invalid argument: 'alignment' has no effect!\n", __func__, __LINE__);
|
|
|
|
bool has_shadow = false;
|
|
if (!tableLookup(L, "has_shadow", has_shadow))
|
|
{
|
|
std::string tmp1 = "false";
|
|
if (tableLookup(L, "has_shadow", tmp1))
|
|
paramBoolDeprecated(L, tmp1.c_str());
|
|
has_shadow = (tmp1 == "true" || tmp1 == "1" || tmp1 == "yes");
|
|
}
|
|
tableLookup(L, "color_frame" , color_frame);
|
|
tableLookup(L, "color_background" , color_background);
|
|
tableLookup(L, "color_shadow" , color_shadow);
|
|
tableLookup(L, "transparency" , transparency);
|
|
|
|
checkMagicMask(color_frame);
|
|
checkMagicMask(color_background);
|
|
checkMagicMask(color_shadow);
|
|
|
|
CComponentsForm* pw = (parent && parent->w) ? parent->w->getBodyObject() : NULL;
|
|
|
|
CLuaPicture **udata = (CLuaPicture **) lua_newuserdata(L, sizeof(CLuaPicture *));
|
|
*udata = new CLuaPicture();
|
|
(*udata)->cp = new CComponentsPicture(x, y, dx, dy, image_name, pw, has_shadow, (fb_pixel_t)color_frame, (fb_pixel_t)color_background, (fb_pixel_t)color_shadow, transparency);
|
|
(*udata)->parent = pw;
|
|
luaL_getmetatable(L, "cpicture");
|
|
lua_setmetatable(L, -2);
|
|
return 1;
|
|
}
|
|
|
|
int CLuaInstance::CPicturePaint(lua_State *L)
|
|
{
|
|
lua_assert(lua_istable(L,1));
|
|
CLuaPicture *m = CPictureCheck(L, 1);
|
|
if (!m) return 0;
|
|
|
|
bool do_save_bg = true;
|
|
if (!tableLookup(L, "do_save_bg", do_save_bg))
|
|
{
|
|
std::string tmp = "true";
|
|
if (tableLookup(L, "do_save_bg", tmp))
|
|
paramBoolDeprecated(L, tmp.c_str());
|
|
do_save_bg = (tmp == "true" || tmp == "1" || tmp == "yes");
|
|
}
|
|
m->cp->paint(do_save_bg);
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::CPictureHide(lua_State *L)
|
|
{
|
|
lua_assert(lua_istable(L,1));
|
|
CLuaPicture *m = CPictureCheck(L, 1);
|
|
if (!m) return 0;
|
|
|
|
bool no_restore = false;
|
|
if (!tableLookup(L, "no_restore", no_restore))
|
|
{
|
|
std::string tmp = "false";
|
|
if (tableLookup(L, "no_restore", tmp))
|
|
paramBoolDeprecated(L, tmp.c_str());
|
|
no_restore = (tmp == "true" || tmp == "1" || tmp == "yes");
|
|
}
|
|
if (m->parent) {
|
|
m->cp->setPicture("");
|
|
m->cp->paint();
|
|
} else
|
|
m->cp->hide(no_restore);
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::CPictureSetPicture(lua_State *L)
|
|
{
|
|
lua_assert(lua_istable(L,1));
|
|
CLuaPicture *m = CPictureCheck(L, 1);
|
|
if (!m) return 0;
|
|
|
|
std::string image_name = "";
|
|
tableLookup(L, "image", image_name);
|
|
|
|
m->cp->setPicture(image_name);
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::CPictureDelete(lua_State *L)
|
|
{
|
|
DBG("CLuaInstance::%s %d\n", __func__, lua_gettop(L));
|
|
CLuaPicture *m = CPictureCheck(L, 1);
|
|
if (!m) return 0;
|
|
|
|
delete m;
|
|
return 0;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|
|
|
|
CLuaConfigFile *CLuaInstance::LuaConfigFileCheck(lua_State *L, int n)
|
|
{
|
|
return *(CLuaConfigFile **) luaL_checkudata(L, n, "configfile");
|
|
}
|
|
|
|
void CLuaInstance::LuaConfigFileRegister(lua_State *L)
|
|
{
|
|
luaL_Reg meth[] = {
|
|
{ "new", CLuaInstance::LuaConfigFileNew },
|
|
{ "loadConfig", CLuaInstance::LuaConfigFileLoadConfig },
|
|
{ "saveConfig", CLuaInstance::LuaConfigFileSaveConfig },
|
|
{ "clear", CLuaInstance::LuaConfigFileClear },
|
|
{ "getString", CLuaInstance::LuaConfigFileGetString },
|
|
{ "setString", CLuaInstance::LuaConfigFileSetString },
|
|
{ "getInt32", CLuaInstance::LuaConfigFileGetInt32 },
|
|
{ "setInt32", CLuaInstance::LuaConfigFileSetInt32 },
|
|
{ "getBool", CLuaInstance::LuaConfigFileGetBool },
|
|
{ "setBool", CLuaInstance::LuaConfigFileSetBool },
|
|
{ "__gc", CLuaInstance::LuaConfigFileDelete },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
luaL_newmetatable(L, "configfile");
|
|
luaL_setfuncs(L, meth, 0);
|
|
lua_pushvalue(L, -1);
|
|
lua_setfield(L, -1, "__index");
|
|
lua_setglobal(L, "configfile");
|
|
}
|
|
|
|
int CLuaInstance::LuaConfigFileNew(lua_State *L)
|
|
{
|
|
CLuaConfigFile **udata = (CLuaConfigFile **) lua_newuserdata(L, sizeof(CLuaConfigFile *));
|
|
*udata = new CLuaConfigFile();
|
|
(*udata)->c = new CConfigFile('\t');
|
|
luaL_getmetatable(L, "configfile");
|
|
lua_setmetatable(L, -2);
|
|
return 1;
|
|
}
|
|
|
|
int CLuaInstance::LuaConfigFileLoadConfig(lua_State *L)
|
|
{
|
|
CLuaConfigFile *c = LuaConfigFileCheck(L, 1);
|
|
if (!c) return 0;
|
|
|
|
const char *fname = luaL_checkstring(L, 2);
|
|
bool ret = c->c->loadConfig(fname);
|
|
lua_pushboolean(L, ret);
|
|
return 1;
|
|
}
|
|
|
|
int CLuaInstance::LuaConfigFileSaveConfig(lua_State *L)
|
|
{
|
|
CLuaConfigFile *c = LuaConfigFileCheck(L, 1);
|
|
if (!c) return 0;
|
|
|
|
const char *fname = luaL_checkstring(L, 2);
|
|
bool ret = c->c->saveConfig(fname);
|
|
lua_pushboolean(L, ret);
|
|
return 1;
|
|
}
|
|
|
|
int CLuaInstance::LuaConfigFileClear(lua_State *L)
|
|
{
|
|
CLuaConfigFile *c = LuaConfigFileCheck(L, 1);
|
|
if (!c) return 0;
|
|
|
|
c->c->clear();
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::LuaConfigFileGetString(lua_State *L)
|
|
{
|
|
CLuaConfigFile *c = LuaConfigFileCheck(L, 1);
|
|
if (!c) return 0;
|
|
int numargs = lua_gettop(L);
|
|
|
|
std::string ret;
|
|
const char *key = luaL_checkstring(L, 2);
|
|
const char *defaultVal = "";
|
|
if (numargs > 2)
|
|
defaultVal = luaL_checkstring(L, 3);
|
|
ret = c->c->getString(key, defaultVal);
|
|
lua_pushstring(L, ret.c_str());
|
|
return 1;
|
|
}
|
|
|
|
int CLuaInstance::LuaConfigFileSetString(lua_State *L)
|
|
{
|
|
CLuaConfigFile *c = LuaConfigFileCheck(L, 1);
|
|
if (!c) return 0;
|
|
|
|
const char *key = luaL_checkstring(L, 2);
|
|
const char *val = luaL_checkstring(L, 3);
|
|
c->c->setString(key, val);
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::LuaConfigFileGetInt32(lua_State *L)
|
|
{
|
|
CLuaConfigFile *c = LuaConfigFileCheck(L, 1);
|
|
if (!c) return 0;
|
|
int numargs = lua_gettop(L);
|
|
|
|
int ret;
|
|
const char *key = luaL_checkstring(L, 2);
|
|
int defaultVal = 0;
|
|
if (numargs > 2)
|
|
defaultVal = luaL_checkint(L, 3);
|
|
ret = c->c->getInt32(key, defaultVal);
|
|
lua_pushinteger(L, ret);
|
|
return 1;
|
|
}
|
|
|
|
int CLuaInstance::LuaConfigFileSetInt32(lua_State *L)
|
|
{
|
|
CLuaConfigFile *c = LuaConfigFileCheck(L, 1);
|
|
if (!c) return 0;
|
|
|
|
const char *key = luaL_checkstring(L, 2);
|
|
int val = luaL_checkint(L, 3);
|
|
c->c->setInt32(key, val);
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::LuaConfigFileGetBool(lua_State *L)
|
|
{
|
|
CLuaConfigFile *c = LuaConfigFileCheck(L, 1);
|
|
if (!c) return 0;
|
|
int numargs = lua_gettop(L);
|
|
|
|
bool ret;
|
|
const char *key = luaL_checkstring(L, 2);
|
|
bool defaultVal = false;
|
|
if (numargs > 2)
|
|
defaultVal = _luaL_checkbool(L, 3);
|
|
ret = c->c->getBool(key, defaultVal);
|
|
lua_pushboolean(L, ret);
|
|
return 1;
|
|
}
|
|
|
|
int CLuaInstance::LuaConfigFileSetBool(lua_State *L)
|
|
{
|
|
CLuaConfigFile *c = LuaConfigFileCheck(L, 1);
|
|
if (!c) return 0;
|
|
|
|
const char *key = luaL_checkstring(L, 2);
|
|
bool val = _luaL_checkbool(L, 3);
|
|
c->c->setBool(key, val);
|
|
return 0;
|
|
}
|
|
|
|
int CLuaInstance::LuaConfigFileDelete(lua_State *L)
|
|
{
|
|
CLuaConfigFile *c = LuaConfigFileCheck(L, 1);
|
|
if (!c) return 0;
|
|
delete c;
|
|
return 0;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|