2014-09-27 09:25:14 +02:00
|
|
|
/*
|
|
|
|
* skindesigner.c: A plugin for the Video Disk Recorder
|
|
|
|
*
|
|
|
|
* See the README file for copyright information and how to reach the author.
|
|
|
|
*
|
|
|
|
* $Id$
|
|
|
|
*/
|
|
|
|
#include <getopt.h>
|
|
|
|
#include <vdr/plugin.h>
|
|
|
|
|
|
|
|
#define DEFINE_CONFIG 1
|
|
|
|
#include "config.h"
|
|
|
|
#include "designer.h"
|
|
|
|
#include "setup.h"
|
2014-11-15 09:47:22 +01:00
|
|
|
#include "services.h"
|
2014-09-27 09:25:14 +02:00
|
|
|
|
|
|
|
#if defined(APIVERSNUM) && APIVERSNUM < 20000
|
|
|
|
#error "VDR-2.0.0 API version or greater is required!"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2014-11-29 18:16:34 +01:00
|
|
|
static const char *VERSION = "0.0.8";
|
2014-09-27 09:25:14 +02:00
|
|
|
static const char *DESCRIPTION = "SkinDesigner";
|
|
|
|
static const char *MAINMENUENTRY = "Skin Designer";
|
|
|
|
|
|
|
|
class cPluginSkinDesigner : public cPlugin {
|
|
|
|
private:
|
2014-10-03 15:54:23 +02:00
|
|
|
vector<cSkinDesigner*> skins;
|
2014-09-27 09:25:14 +02:00
|
|
|
public:
|
|
|
|
cPluginSkinDesigner(void);
|
|
|
|
virtual ~cPluginSkinDesigner();
|
|
|
|
virtual const char *Version(void) { return VERSION; }
|
|
|
|
virtual const char *Description(void) { return DESCRIPTION; }
|
|
|
|
virtual const char *CommandLineHelp(void);
|
|
|
|
virtual bool ProcessArgs(int argc, char *argv[]);
|
|
|
|
virtual bool Initialize(void);
|
|
|
|
virtual bool Start(void);
|
|
|
|
virtual void Stop(void);
|
|
|
|
virtual void Housekeeping(void);
|
|
|
|
virtual void MainThreadHook(void);
|
|
|
|
virtual cString Active(void);
|
|
|
|
virtual time_t WakeupTime(void);
|
|
|
|
virtual const char *MainMenuEntry(void) {return NULL;}
|
|
|
|
virtual cOsdObject *MainMenuAction(void);
|
|
|
|
virtual cMenuSetupPage *SetupMenu(void);
|
|
|
|
virtual bool SetupParse(const char *Name, const char *Value);
|
|
|
|
virtual bool Service(const char *Id, void *Data = NULL);
|
|
|
|
virtual const char **SVDRPHelpPages(void);
|
|
|
|
virtual cString SVDRPCommand(const char *Command, const char *Option, int &ReplyCode);
|
|
|
|
};
|
|
|
|
|
|
|
|
cPluginSkinDesigner::cPluginSkinDesigner(void) {
|
|
|
|
}
|
|
|
|
|
|
|
|
cPluginSkinDesigner::~cPluginSkinDesigner() {
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *cPluginSkinDesigner::CommandLineHelp(void) {
|
|
|
|
return
|
|
|
|
" -s <SKINPATH>, --skinpath=<SKINPATH> Set directory where xml skins are stored\n"
|
2014-10-03 15:54:23 +02:00
|
|
|
" -l <LOGOPATH>, --logopath=<LOGOPATH> Set directory where a common logo set for all skins is stored\n"
|
2014-09-27 09:25:14 +02:00
|
|
|
" -e <EPGIMAGESPATH>, --epgimages=<IMAGESPATH> Set directory where epgimages are stored\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
bool cPluginSkinDesigner::ProcessArgs(int argc, char *argv[]) {
|
|
|
|
// Implement command line argument processing here if applicable.
|
|
|
|
static const struct option long_options[] = {
|
|
|
|
{ "epgimages", required_argument, NULL, 'e' },
|
2014-10-03 15:54:23 +02:00
|
|
|
{ "logopath", required_argument, NULL, 'l' },
|
2014-09-27 09:25:14 +02:00
|
|
|
{ "skinpath", required_argument, NULL, 's' },
|
|
|
|
{ 0, 0, 0, 0 }
|
|
|
|
};
|
|
|
|
|
|
|
|
int c;
|
2014-10-03 15:54:23 +02:00
|
|
|
while ((c = getopt_long(argc, argv, "e:s:l:", long_options, NULL)) != -1) {
|
2014-09-27 09:25:14 +02:00
|
|
|
switch (c) {
|
|
|
|
case 'e':
|
|
|
|
config.SetEpgImagePath(cString(optarg));
|
|
|
|
break;
|
2014-10-03 15:54:23 +02:00
|
|
|
case 'l':
|
|
|
|
config.SetLogoPath(cString(optarg));
|
|
|
|
break;
|
2014-09-27 09:25:14 +02:00
|
|
|
case 's':
|
|
|
|
config.SetSkinPath(cString(optarg));
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool cPluginSkinDesigner::Initialize(void) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool cPluginSkinDesigner::Start(void) {
|
2014-11-12 16:58:01 +01:00
|
|
|
cXmlParser::InitLibXML();
|
2014-11-23 13:07:43 +01:00
|
|
|
cImageImporterSVG::InitLibRSVG();
|
2014-10-03 15:54:23 +02:00
|
|
|
bool trueColorAvailable = true;
|
2014-09-27 09:25:14 +02:00
|
|
|
if (!cOsdProvider::SupportsTrueColor()) {
|
2014-09-28 10:47:54 +02:00
|
|
|
esyslog("skindesigner: No TrueColor OSD found! Using default Skin LCARS!");
|
2014-10-03 15:54:23 +02:00
|
|
|
trueColorAvailable = false;
|
2014-09-27 09:25:14 +02:00
|
|
|
} else
|
2014-09-28 10:47:54 +02:00
|
|
|
dsyslog("skindesigner: TrueColor OSD found");
|
2014-10-03 15:54:23 +02:00
|
|
|
config.SetPathes();
|
|
|
|
config.ReadSkins();
|
|
|
|
config.InitSkinIterator();
|
|
|
|
string skin = "";
|
|
|
|
while (config.GetSkin(skin)) {
|
|
|
|
cSkinDesigner *newSkin = new cSkinDesigner(skin);
|
|
|
|
skins.push_back(newSkin);
|
|
|
|
if (!trueColorAvailable) {
|
|
|
|
newSkin->ActivateBackupSkin();
|
|
|
|
}
|
|
|
|
}
|
2014-10-04 10:10:04 +02:00
|
|
|
if (skins.size() == 0) {
|
|
|
|
esyslog("skindesigner: no skins found! Using default Skin LCARS!");
|
|
|
|
}
|
2014-10-03 15:54:23 +02:00
|
|
|
return true;
|
2014-09-27 09:25:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void cPluginSkinDesigner::Stop(void) {
|
|
|
|
delete imgCache;
|
|
|
|
delete fontManager;
|
2014-11-12 16:58:01 +01:00
|
|
|
cXmlParser::CleanupLibXML();
|
2014-09-27 09:25:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void cPluginSkinDesigner::Housekeeping(void) {
|
|
|
|
}
|
|
|
|
|
|
|
|
void cPluginSkinDesigner::MainThreadHook(void) {
|
|
|
|
}
|
|
|
|
|
|
|
|
cString cPluginSkinDesigner::Active(void) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
time_t cPluginSkinDesigner::WakeupTime(void) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
cOsdObject *cPluginSkinDesigner::MainMenuAction(void) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
cMenuSetupPage *cPluginSkinDesigner::SetupMenu(void) {
|
|
|
|
return new cSkinDesignerSetup();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool cPluginSkinDesigner::SetupParse(const char *Name, const char *Value) {
|
|
|
|
return config.SetupParse(Name, Value);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool cPluginSkinDesigner::Service(const char *Id, void *Data) {
|
2014-11-15 09:47:22 +01:00
|
|
|
if (Data == NULL)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (strcmp(Id, "RegisterPlugin") == 0) {
|
|
|
|
RegisterPlugin* call = (RegisterPlugin*) Data;
|
|
|
|
if (call->menus.size() < 1) {
|
|
|
|
esyslog("skindesigner: error - plugin without menus registered");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
config.AddPlugin(call->name, call->menus);
|
|
|
|
dsyslog("skindesigner: plugin %s has registered %d templates", call->name.c_str(), call->menus.size());
|
|
|
|
return true;
|
|
|
|
} else if (strcmp(Id, "GetDisplayMenu") == 0) {
|
|
|
|
GetDisplayMenu* call = (GetDisplayMenu*) Data;
|
|
|
|
cSkin *current = Skins.Current();
|
|
|
|
for (vector<cSkinDesigner*>::iterator skin = skins.begin(); skin != skins.end(); skin++) {
|
|
|
|
if (*skin == current) {
|
|
|
|
cSDDisplayMenu *displayMenu = (*skin)->GetDisplayMenu();
|
|
|
|
if (displayMenu) {
|
|
|
|
call->displayMenu = displayMenu;
|
|
|
|
return true;
|
|
|
|
} else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-09-27 09:25:14 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char **cPluginSkinDesigner::SVDRPHelpPages(void) {
|
|
|
|
static const char *HelpPages[] = {
|
|
|
|
"RELD\n"
|
|
|
|
" force reload of templates and caches",
|
2014-10-11 16:31:39 +02:00
|
|
|
"SCTK\n"
|
|
|
|
" Set custom Token name = value",
|
|
|
|
"LCTK\n"
|
|
|
|
" List custom Tokens",
|
2014-09-27 09:25:14 +02:00
|
|
|
"LSTF\n"
|
|
|
|
" List available Fonts",
|
|
|
|
0
|
|
|
|
};
|
|
|
|
return HelpPages;
|
|
|
|
}
|
|
|
|
|
|
|
|
cString cPluginSkinDesigner::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode) {
|
2014-10-03 15:54:23 +02:00
|
|
|
|
|
|
|
cSkinDesigner *activeSkin = NULL;
|
|
|
|
for (vector<cSkinDesigner*>::iterator skin = skins.begin(); skin != skins.end(); skin++) {
|
|
|
|
string activeSkinName = Setup.OSDSkin;
|
|
|
|
string currentSkinName = (*skin)->Description();
|
|
|
|
if (!currentSkinName.compare(activeSkinName)) {
|
|
|
|
activeSkin = *skin;
|
|
|
|
break;
|
2014-09-27 09:25:14 +02:00
|
|
|
}
|
2014-10-03 15:54:23 +02:00
|
|
|
}
|
|
|
|
|
2014-10-11 16:31:39 +02:00
|
|
|
if (!activeSkin) {
|
|
|
|
ReplyCode = 550;
|
|
|
|
return "";
|
|
|
|
}
|
2014-10-03 15:54:23 +02:00
|
|
|
|
|
|
|
if (strcasecmp(Command, "RELD") == 0) {
|
|
|
|
activeSkin->Reload();
|
2014-10-11 16:31:39 +02:00
|
|
|
ReplyCode = 250;
|
2014-10-03 15:54:23 +02:00
|
|
|
return "SKINDESIGNER reload of templates and caches forced.";
|
2014-09-27 09:25:14 +02:00
|
|
|
} else if (strcasecmp(Command, "LSTF") == 0) {
|
2014-10-03 15:54:23 +02:00
|
|
|
activeSkin->ListAvailableFonts();
|
2014-10-11 16:31:39 +02:00
|
|
|
ReplyCode = 250;
|
2014-10-03 15:54:23 +02:00
|
|
|
return "SKINDESIGNER available fonts listed in syslog.";
|
2014-10-11 16:31:39 +02:00
|
|
|
} else if (strcasecmp(Command, "SCTK") == 0) {
|
|
|
|
if (!Option) {
|
|
|
|
ReplyCode = 501;
|
|
|
|
return "SKINDESIGNER SCTK Error: no Token name = value set";
|
|
|
|
}
|
|
|
|
bool optionOk = activeSkin->SetCustomToken(Option);
|
|
|
|
if (optionOk) {
|
|
|
|
ReplyCode = 250;
|
|
|
|
return cString::sprintf("SKINDESIGNER Set custom Token %s", Option);
|
|
|
|
} else {
|
|
|
|
ReplyCode = 501;
|
|
|
|
return cString::sprintf("SKINDESIGNER Invalid custom Token %s", Option);
|
|
|
|
}
|
|
|
|
} else if (strcasecmp(Command, "LCTK") == 0) {
|
|
|
|
activeSkin->ListCustomTokens();
|
|
|
|
ReplyCode = 250;
|
|
|
|
return "SKINDESIGNER Custom Tokens listed in Log";
|
2014-09-27 09:25:14 +02:00
|
|
|
}
|
2014-10-11 16:31:39 +02:00
|
|
|
ReplyCode = 502;
|
|
|
|
return "";
|
2014-09-27 09:25:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
VDRPLUGINCREATOR(cPluginSkinDesigner); // Don't touch this!
|