summaryrefslogtreecommitdiff
path: root/vlookup.c
diff options
context:
space:
mode:
authorhorchi <vdr@jwendel.de>2017-03-05 16:47:41 +0100
committerhorchi <vdr@jwendel.de>2017-03-05 16:47:41 +0100
commit22ffee20bbacbc3378e4ba0df5b7f0c3daaeffc0 (patch)
treede46c945c62d43d1febb027b5bfa075e58c5b69a /vlookup.c
downloadvdr-plugin-graphtftng-master.tar.gz
vdr-plugin-graphtftng-master.tar.bz2
Diffstat (limited to 'vlookup.c')
-rw-r--r--vlookup.c798
1 files changed, 798 insertions, 0 deletions
diff --git a/vlookup.c b/vlookup.c
new file mode 100644
index 0000000..0aa84a9
--- /dev/null
+++ b/vlookup.c
@@ -0,0 +1,798 @@
+/*
+ * GraphTFT plugin for the Video Disk Recorder
+ *
+ * vlookup.c
+ *
+ * (c) 2007-2015 Jörg Wendel
+ *
+ * This code is distributed under the terms and conditions of the
+ * GNU GENERAL PUBLIC LICENSE. See the file COPYING for details.
+ */
+
+#include <display.h>
+#include <scraper2vdr.h>
+
+//***************************************************************************
+// Copied vorm VDR code!
+//***************************************************************************
+
+#define FULLMATCH 1000
+
+eTimerMatch Matches(const cTimer* ti, const cEventCopy* Event)
+{
+ if (ti->HasFlags(tfActive) && ti->Channel()->GetChannelID() == Event->ChannelID())
+ {
+ int overlap = 0;
+ bool UseVps = ti->HasFlags(tfVps) && Event->Vps();
+
+ if (UseVps)
+ overlap = (ti->StartTime() == Event->Vps()) ? FULLMATCH + (Event->IsRunning() ? 200 : 100) : 0;
+
+ if (!overlap)
+ {
+ if (ti->StartTime() <= Event->StartTime() && Event->EndTime() <= ti->StopTime())
+ overlap = FULLMATCH;
+ else if (ti->StopTime() <= Event->StartTime() || Event->EndTime() <= ti->StartTime())
+ overlap = 0;
+ else
+ overlap = (min(ti->StopTime(), Event->EndTime()) - max(ti->StartTime(), Event->StartTime())) * FULLMATCH / max(Event->Duration(), 1);
+ }
+
+ if (UseVps)
+ return overlap > FULLMATCH ? tmFull : tmNone;
+
+ return overlap >= FULLMATCH ? tmFull : overlap > 0 ? tmPartial : tmNone;
+ }
+
+ return tmNone;
+}
+
+#if VDRVERSNUM < 10733
+ enum eTimerMatch { tmNone, tmPartial, tmFull };
+#endif
+
+const cTimer* getTimerMatch(const cTimers* timers, const cEventCopy* event, eTimerMatch* Match)
+{
+ const cTimer* t = 0;
+ eTimerMatch m = tmNone;
+
+ for (const cTimer* ti = timers->First(); ti; ti = timers->Next(ti))
+ {
+ eTimerMatch tm = Matches(ti, event);
+
+ if (tm > m)
+ {
+ t = ti;
+ m = tm;
+
+ if (m == tmFull)
+ break;
+ }
+ }
+
+ if (Match)
+ *Match = m;
+
+ return t;
+}
+
+//***************************************************************************
+// Variable of Group
+//***************************************************************************
+
+const char* variableGroup(const char* value, const char* group, const char*& var)
+{
+ if (!group)
+ return 0;
+
+ if (strncasecmp(value, group, strlen(group)) == 0)
+ {
+ var = value + strlen(group);
+ return group;
+ }
+
+ return 0;
+}
+
+//***************************************************************************
+// Lookup Variable
+//***************************************************************************
+
+int cDisplayItem::lookupVariable(const char* name, string& value, const char* fmt)
+{
+ const char* p;
+ int status;
+
+ value = "";
+ p = variable(name, fmt, status);
+
+ if (p)
+ {
+ value = p;
+ return success;
+ }
+
+ if (status == success)
+ return fail;
+
+ // nothing found ... -> check theme for global variable
+
+ if (cThemeItem::lookupVariable(name, value, fmt) == success)
+ {
+ if (fmt && (strcasestr(name, "TIME") || strcasestr(name, "DATE")))
+ {
+ char buf[100];
+
+ if (formatDateTime(atol(value.c_str()), fmt, buf, sizeof(buf)))
+ value = buf;
+ }
+
+ return success;
+ }
+
+ // variable unknown :(
+
+ tell(0, "Unexpected variable '%s'", name);
+
+ return fail;
+}
+
+//***************************************************************************
+// Variable
+//***************************************************************************
+
+const char* cDisplayItem::variable(const char* name, const char* fmt, int& status)
+{
+ static char buf[1000];
+ const char* p;
+ int total, current;
+ const char* var;
+ const char* group;
+
+ status = success;
+
+ if ((var = strchr(name, '.')))
+ {
+ cDisplayItem* item = 0;
+ char id[50+TB];
+
+ snprintf(id, 50, "%.*s", (int)(var-name), name);
+ var++;
+
+ if (!(item = section->getItemById(id)))
+ {
+ // no item with this id found -> should be a reference to a variable file,
+ // will processed by 'cThemeItem::lookupVariable'
+
+ status = fail;
+
+ return 0;
+ }
+
+ tell(4, "found item '%s' (%s), lookup '%s'", item->Id().c_str(), name, var);
+
+ if (strcasecmp(var, "X") == 0)
+ return Str::toStr(item->lastX);
+ if (strcasecmp(var, "Y") == 0)
+ return Str::toStr(item->lastY);
+ if (strcasecmp(var, "Width") == 0)
+ return Str::toStr(item->lastWidth);
+ if (strcasecmp(var, "Height") == 0)
+ return Str::toStr(item->lastHeight);
+ else
+ tell(0, "Unexpected theme variable %s in %s", var, name);
+
+ return "0";
+ }
+
+ if ((group = variableGroup(name, "music", var)))
+ {
+ p = musicVariable(group, var, fmt, status);
+
+ if (status == success)
+ return p;
+ }
+
+ else if ((group = variableGroup(name, "recording", var))
+ || (group = variableGroup(name, "replay", var))
+ || (group = variableGroup(name, "rowRecording", var))
+ || (group = variableGroup(name, "selectedRowRecording", var)))
+ {
+ const cRecording* recording = 0;
+
+#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
+ cRecordingsLock recordingsLock(false);
+ const cRecordings* recordings = recordingsLock.Recordings();
+#else
+ cRecordings* recordings = &Recordings;
+#endif
+
+ if (strcmp(group, "recording") == 0)
+ recording = recordings->GetByName(vdrStatus->_recording.c_str());
+ else if (strcmp(group, "replay") == 0)
+ recording = recordings->GetByName(vdrStatus->_replay.fileName.c_str());
+ else if (strcmp(group, "rowRecording") == 0)
+ recording = vdrStatus->_menu.drawingRow == na ?
+ 0 : vdrStatus->_menu.items[vdrStatus->_menu.drawingRow].recording;
+ else if (strcmp(group, "selectedRowRecording") == 0)
+ recording = vdrStatus->_menu.currentRow == na ?
+ 0 : vdrStatus->_menu.items[vdrStatus->_menu.currentRow].recording;
+
+ // recording variables
+
+ if (!recording && strcmp(group, "replay") != 0)
+ {
+ tell(0, "Missing '%s' info, can't lookup variable for '%s'",
+ name, vdrStatus->_recording.c_str());
+
+ return 0;
+ }
+
+ if (vdrStatus->_replay.control)
+ {
+ if (strcasecmp(var, "Speed") == 0)
+ return Str::toStr(replayModeValue(rmSpeed));
+ else if (strcasecmp(var, "Play") == 0)
+ return Str::toStr(replayModeValue(rmPlay));
+ else if (strcasecmp(var, "Forward") == 0)
+ return Str::toStr(replayModeValue(rmForward));
+ else if (strcasecmp(var, "Current") == 0)
+ {
+ vdrStatus->_replay.control->GetIndex(current, total);
+ return formatDateTime((current ? current : 1) / (int)vdrStatus->_replay.control->FramesPerSecond(),
+ fmt, buf, sizeof(buf), yes);
+ }
+ else if (strcasecmp(var, "Total") == 0)
+ {
+ vdrStatus->_replay.control->GetIndex(current, total);
+ return formatDateTime((total ? total : 1) / (int)vdrStatus->_replay.control->FramesPerSecond(),
+ fmt, buf, sizeof(buf), yes);
+ }
+ else if (strcasecmp(var, "RawCurrent") == 0)
+ {
+ vdrStatus->_replay.control->GetIndex(current, total);
+ return Str::toStr(current);
+ }
+ else if (strcasecmp(var, "RawTotal") == 0)
+ {
+ vdrStatus->_replay.control->GetIndex(current, total);
+ return Str::toStr(total);
+ }
+ }
+
+ if (recording)
+ {
+ if (strcasecmp(var, "Title") == 0)
+ return formatString(Str::notNull(recording->Info()->Title()), fmt, buf, sizeof(buf));
+ else if (strcasecmp(var, "Path") == 0)
+ return formatString(Str::notNull(recording->FileName()), fmt, buf, sizeof(buf));
+ else if (strcasecmp(var, "Time") == 0)
+ return formatDateTime(recording->Start(), fmt, buf, sizeof(buf));
+ else if (strcasecmp(var, "EventID") == 0)
+ return Str::toStr(!recording->Info() ? na : (int)recording->Info()->GetEvent()->EventID());
+ else if (strcasecmp(var, "SubTitle") == 0)
+ return Str::notNull(recording->Info()->ShortText());
+ else if (strcasecmp(var, "Description") == 0)
+ return Str::notNull(recording->Info()->Description());
+ else if (strcasecmp(var, "Channel") == 0)
+ return formatString(Str::notNull(recording->Info()->ChannelName()), fmt, buf, sizeof(buf));
+ else if (strcasecmp(var, "Banner") == 0)
+ {
+ string mediaPath;
+ string posterPath;
+
+ if (getScraperMediaPath(0, recording, mediaPath, posterPath) == success)
+ tell(5, "Got banner path '%s'", mediaPath.c_str());
+
+ return mediaPath.c_str();
+ }
+ else if (strcasecmp(var, "Poster") == 0)
+ {
+ string mediaPath;
+ string posterPath;
+
+ if (getScraperMediaPath(0, recording, mediaPath, posterPath) == success)
+ tell(5, "Got poster path '%s'", posterPath.c_str());
+
+ return posterPath.c_str();
+ }
+ }
+
+ else
+ {
+ if (strcasecmp(var, "Title") == 0)
+ return formatString(Str::notNull(vdrStatus->_replay.name.c_str()), fmt, buf, sizeof(buf));
+ else if (strcasecmp(var, "EventID") == 0)
+ return Str::toStr(na);
+ else if (strcasecmp(var, "SubTitle") == 0)
+ return "";
+ else if (strcasecmp(var, "Channel") == 0)
+ return "";
+ else if (strcasecmp(var, "Path") == 0)
+ return formatString(Str::notNull(vdrStatus->_replay.fileName.c_str()), fmt, buf, sizeof(buf));
+ else if (strcasecmp(var, "Time") == 0)
+ return "";
+ else if (strcasecmp(var, "Description") == 0)
+ return "no details available";
+ }
+ }
+
+ else if ((group = variableGroup(name, "volume", var)))
+ {
+ if (strcasecmp(var, "Mute") == 0)
+ return Str::toStr(vdrStatus->_mute);
+ else if (strcasecmp(var, "Level") == 0)
+ return Str::toStr(vdrStatus->_volume);
+ }
+
+ else if ((group = variableGroup(name, "event", var))
+ || (group = variableGroup(name, "following", var))
+ || (group = variableGroup(name, "present", var))
+ || (group = variableGroup(name, "rowEvent", var))
+ || (group = variableGroup(name, "selectedRowEvent", var)))
+ {
+ tell(5, "lookup variable '%s' of group '%s'", var, group);
+
+ eTimerMatch timerMatch = tmNone;
+ cEventCopy* event = 0;
+ const cChannel* channel = 0;
+
+#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
+ cChannelsLock channelsLock(false);
+ const cChannels* channels = channelsLock.Channels();
+#else
+ cChannels* channels = &Channels;
+#endif
+
+ if (strcmp(group, "event") == 0)
+ {
+ if (!vdrStatus->_event.isEmpty())
+ {
+ event = &vdrStatus->_event;
+ channel = channels->GetByChannelID(event->ChannelID());
+ }
+ }
+ else if (strcmp(group, "present") == 0)
+ {
+ if (!vdrStatus->_presentEvent.isEmpty())
+ event = &vdrStatus->_presentEvent;
+
+ channel = vdrStatus->_presentChannel;
+ }
+ else if (strcmp(group, "following") == 0)
+ {
+ if (!vdrStatus->_followingEvent.isEmpty())
+ event = &vdrStatus->_followingEvent;
+
+ channel = vdrStatus->_presentChannel;
+ }
+ else if (strcmp(group, "rowEvent") == 0)
+ {
+ if (vdrStatus->_menu.drawingRow != na)
+ event = &vdrStatus->_menu.items[vdrStatus->_menu.drawingRow].event;
+ channel = vdrStatus->_menu.drawingRow == na ?
+ 0 : vdrStatus->_menu.items[vdrStatus->_menu.drawingRow].channel;
+ }
+ else if (strcmp(group, "selectedRowEvent") == 0)
+ {
+ if (vdrStatus->_menu.currentRow != na)
+ event = &vdrStatus->_menu.items[vdrStatus->_menu.currentRow].event;
+
+ channel = vdrStatus->_menu.currentRow == na ?
+ 0 : vdrStatus->_menu.items[vdrStatus->_menu.currentRow].channel;
+ }
+
+ // this items don't need a channel
+
+ *buf = 0;
+
+ if (strcasecmp(var, "Title") == 0)
+ {
+ if (!event)
+ {
+ // No EPG Data available
+ // RDS is available only for presentTitle
+
+ if ((vdrStatus->_rds.text.empty()) ||
+ (strcmp(group, "present") != 0))
+ {
+ if (!channel)
+ return buf;
+
+ return channel->Name();
+ }
+ return vdrStatus->_rds.text.c_str();
+ }
+
+ return Str::notNull(event->Title());
+ }
+ else if (strcasecmp(var, "SubTitle") == 0)
+ {
+ if (!event)
+ {
+ // No EPG Data available
+ // RDS is available only for presentSubTitle
+
+ if (strcmp(group, "present") == 0)
+ {
+ if (vdrStatus->_rds.title.empty() &&
+ vdrStatus->_rds.artist.empty())
+ {
+ strcpy(buf, tr("No EPG data available."));
+ return buf;
+ }
+
+ sprintf(buf, " %s : %s\n%s : %s", tr("Title"),
+ vdrStatus->_rds.title.c_str(), tr("Artist"),
+ vdrStatus->_rds.artist.c_str());
+ }
+ return buf;
+ }
+
+ return Str::notNull(event->ShortText());
+ }
+ else if (strcasecmp(var, "Description") == 0)
+ {
+ if (!event)
+ return buf; // No EPG Data available
+
+ return Str::notNull(event->Description());
+ }
+
+ if (!channel || !channel->Number())
+ {
+ tell(2, "Info: Can't find channel for '%s' in '%s' of row %d",
+ group, var, vdrStatus->_menu.drawingRow);
+
+ return 0;
+ }
+
+ // this items don't need a event
+
+ if (strcasecmp(var, "ChannelName") == 0)
+ return formatString(channel ? channel->Name() : "", fmt, buf, sizeof(buf));
+ else if (strcasecmp(var, "ChannelId") == 0)
+ return !channel ? "" : strcpy(buf, channel->GetChannelID().ToString());
+ else if (strcasecmp(var, "ChannelNumber") == 0)
+ return Str::toStr(channel ? channel->Number() : 0);
+
+ // check the event
+
+ if (!event)
+ {
+ tell(1, "Info: Missing event for '%s', can't lookup variable in '%s'",
+ group, var);
+
+ return 0;
+ }
+
+ // following items need a event
+
+ // --------------------------
+ // get timers lock
+
+#if defined (APIVERSNUM) && (APIVERSNUM >= 20301)
+ cTimersLock timersLock(false);
+ const cTimers* timers = timersLock.Timers();
+#else
+ cTimers* timers = &Timers;
+#endif
+
+ const cTimer* timer = getTimerMatch(timers, event, &timerMatch);
+
+ if (strcasecmp(var, "ID") == 0)
+ return Str::toStr((int)event->EventID());
+ else if (strcasecmp(var, "StartTime") == 0)
+ return formatDateTime(event->StartTime(), fmt, buf, sizeof(buf));
+ else if (strcasecmp(var, "EndTime") == 0)
+ return formatDateTime(event->EndTime(), fmt, buf, sizeof(buf));
+ else if (strcasecmp(var, "Duration") == 0)
+ return Str::toStr(event->Duration() / 60);
+ else if (strcasecmp(var, "HasTimer") == 0)
+ return timer && timerMatch == tmFull ? "1" : "0";
+ else if (strcasecmp(var, "HasPartialTimer") == 0)
+ return timer && timerMatch == tmPartial ? "1" : "0";
+ else if (strcasecmp(var, "HasPartialTimerBefore") == 0)
+ return timer && timerMatch == tmPartial &&
+ timer->StartTime() >= event->StartTime()
+ ? "1" : "0";
+ else if (strcasecmp(var, "HasPartialTimerAfter") == 0)
+ return timer && timerMatch == tmPartial &&
+ timer->StartTime() < event->StartTime()
+ ? "1" : "0";
+ else if (strcasecmp(var, "IsRunning") == 0)
+ return event->SeenWithin(30) && event->IsRunning() ? "1" : "0";
+ else if (strcasecmp(var, "Elapsed") == 0)
+ return Str::toStr(((int)(time(0)-event->StartTime()) / 60));
+ else if (strcasecmp(var, "Remaining") == 0)
+ {
+ if (time(0) < event->StartTime())
+ return Str::toStr(event->Duration() / 60);
+ else
+ return Str::toStr(((int)(event->EndTime()-time(0)) / 60));
+ }
+ else if (strcasecmp(var, "Progress") == 0)
+ {
+ if (time(0) > event->StartTime())
+ return Str::toStr((int)(100.0 / ((double)event->Duration() / (double)(time(0)-event->StartTime()))));
+ else
+ return Str::toStr((int)(100.0 / ((double)event->Duration() / (double)(event->StartTime()-time(0)))));
+ }
+ else if (strcasecmp(var, "IsRecording") == 0)
+ return timerMatch == tmFull && timer && timer->Recording() ? "1" : "0";
+ else if (strcasecmp(var, "Banner") == 0)
+ {
+ string mediaPath;
+ string posterPath;
+
+ if (getScraperMediaPath(event, 0, mediaPath, posterPath) == success)
+ tell(5, "Got banner path '%s'", mediaPath.c_str());
+
+ return mediaPath.c_str();
+ }
+ else if (strcasecmp(var, "Poster") == 0)
+ {
+ string mediaPath;
+ string posterPath;
+
+ if (getScraperMediaPath(event, 0, mediaPath, posterPath) == success)
+ tell(5, "Got poster path '%s'", posterPath.c_str());
+
+ return posterPath.c_str();
+ }
+ }
+
+ else
+ {
+ if (strcasecmp(name, "channelGroup") == 0)
+ return vdrStatus->_channelGroup.c_str();
+
+ if (strcasecmp(name, "menuTitle") == 0)
+ return vdrStatus->_menu.title.c_str();
+
+ if (strcasecmp(name, "colCount") == 0)
+ return Str::toStr(vdrStatus->_menu.items[vdrStatus->_menu.drawingRow].tabCount);
+
+ if (strcasecmp(name, "rowCount") == 0)
+ return Str::toStr((int)vdrStatus->_menu.items.size());
+
+ if (strcasecmp(name, "visibleRows") == 0)
+ return Str::toStr(vdrStatus->_menu.visibleRows);
+
+ if (strcasecmp(name, "currentRow") == 0)
+ return Str::toStr(vdrStatus->_menu.currentRow);
+
+ if (strcasecmp(name, "touchMenu") == 0)
+ return Str::toStr(vdrStatus->touchMenu);
+
+ if (strcasecmp(name, "themeVersion") == 0)
+ return Thms::theTheme->getThemeVersion().c_str();
+
+ if (strcasecmp(name, "syntaxVersion") == 0)
+ return Thms::theTheme->getSyntaxVersion().c_str();
+
+ if (strcasecmp(name, "themeName") == 0)
+ return Thms::theTheme->getName().c_str();
+
+ if (strcasecmp(name, "vdrVersion") == 0)
+ return VDRVERSION;
+
+ if (strcasecmp(name, "mouseX") == 0)
+ return Str::toStr(vdrStatus->mouseX);
+
+ if (strcasecmp(name, "mouseY") == 0)
+ return Str::toStr(vdrStatus->mouseY);
+
+ if (strcasecmp(name, "mouseKey") == 0)
+ return Str::toStr(vdrStatus->mouseKey);
+
+ if (strcasecmp(name, "calibrationInstruction") == 0)
+ return vdrStatus->calibration.instruction.c_str();
+
+ if (strcasecmp(name, "calibrationInfo") == 0)
+ return vdrStatus->calibration.info.c_str();
+
+ if (strcasecmp(name, "calibrationCursorX") == 0)
+ return Str::toStr(vdrStatus->calibration.cursorX);
+
+ if (strcasecmp(name, "calibrationCursorY") == 0)
+ return Str::toStr(vdrStatus->calibration.cursorY);
+
+ if (strcasecmp(name, "calibrationTouchedX") == 0)
+ return Str::toStr(vdrStatus->calibration.lastX);
+
+ if (strcasecmp(name, "calibrationTouchedY") == 0)
+ return Str::toStr(vdrStatus->calibration.lastY);
+
+ if (strcasecmp(name, "calibrationOffsetX") == 0)
+ return Str::toStr(vdrStatus->calibration.settings.offsetX);
+
+ if (strcasecmp(name, "calibrationOffsetY") == 0)
+ return Str::toStr(vdrStatus->calibration.settings.offsetY);
+
+ if (strcasecmp(name, "calibrationScaleX") == 0)
+ return Str::toStr(vdrStatus->calibration.settings.scaleX, 4);
+
+ if (strcasecmp(name, "calibrationScaleY") == 0)
+ return Str::toStr(vdrStatus->calibration.settings.scaleY, 4);
+
+ if (strcasecmp(name, "actRecordingCount") == 0)
+ return Str::toStr(vdrStatus->_timers.countRunning());
+
+ if (strcasecmp(name, "actRecordingName") == 0)
+ return vdrStatus->_timers.firstRunning();
+
+ if (strcasecmp(name, "actTimersRunning") == 0)
+ return Str::toStr(vdrStatus->_timers.running());
+
+ if (strcasecmp(name, "actTimersTitle") == 0)
+ return vdrStatus->_timers.title();
+
+ if (strcasecmp(name, "actTimersFile") == 0)
+ return vdrStatus->_timers.file();
+
+ if (strcasecmp(name, "actTimersStart") == 0)
+ return formatDateTime(vdrStatus->_timers.start(), fmt, buf, sizeof(buf));
+
+ if (strcasecmp(name, "actTimersStop") == 0)
+ return formatDateTime(vdrStatus->_timers.stop(), fmt, buf, sizeof(buf));
+
+ if (strcasecmp(name, "menuText") == 0)
+ return vdrStatus->_menu.text.c_str();
+
+ if (strcasecmp(name, "STR") == 0)
+ return !cDevice::ActualDevice() ? "0" : Str::toStr(cDevice::ActualDevice()->SignalStrength());
+
+ if (strcasecmp(name, "SNR") == 0)
+ return !cDevice::ActualDevice() ? "0" : Str::toStr(cDevice::ActualDevice()->SignalQuality());
+
+ if (strcasecmp(name, "unseenMailCount") == 0)
+ return Str::toStr(vdrStatus->getUnseenMails());
+
+ if (strcasecmp(name, "hasNewMail") == 0)
+ return Str::toStr(vdrStatus->hasNewMail());
+
+ if (strcasecmp(name, "channelHasVtx") == 0)
+ return Str::toStr(vdrStatus->_presentChannel && vdrStatus->_presentChannel->Tpid());
+
+ if (strcasecmp(name, "channelHasMultilang") == 0)
+ return Str::toStr(vdrStatus->_presentChannel && vdrStatus->_presentChannel->Apid(1));
+
+ if (strcasecmp(name, "channelHasDD") == 0)
+ return Str::toStr(vdrStatus->_presentChannel && vdrStatus->_presentChannel->Dpid(0));
+
+ if (strcasecmp(name, "channelIsEncrypted") == 0)
+ return Str::toStr(vdrStatus->_presentChannel && vdrStatus->_presentChannel->Ca());
+
+ if (strcasecmp(name, "channelIsRadio") == 0)
+ {
+ int vp = vdrStatus->_presentChannel ? vdrStatus->_presentChannel->Vpid() : na;
+
+ return Str::toStr(vp == 0 || vp == 1 || vp == 0x1fff);
+ }
+
+ if (strcasecmp(name, "videoSizeHeight") == 0)
+ {
+ int width = 0, height = 0;
+ double aspect;
+
+ if (cDevice::PrimaryDevice())
+ cDevice::PrimaryDevice()->GetVideoSize(width, height, aspect);
+
+ return Str::toStr(height);
+ }
+
+ if (strcasecmp(name, "videoSizeWidth") == 0)
+ {
+ int width = 0, height = 0;
+ double aspect;
+
+ if (cDevice::PrimaryDevice())
+ cDevice::PrimaryDevice()->GetVideoSize(width, height, aspect);
+
+ return Str::toStr(width);
+ }
+
+ if (strcasecmp(name, "time") == 0)
+ {
+ if (strstr(fmt, "%s") || strstr(fmt, "%S") || strstr(fmt, "%T"))
+ {
+ // refresh every 1 second
+
+ if (!_delay)
+ scheduleDrawIn(1000);
+ }
+ else
+ {
+ // refresh at full minute
+
+ scheduleDrawNextFullMinute();
+ }
+
+ return formatDateTime(time(0), fmt, buf, sizeof(buf));
+ }
+
+ if (strcasecmp(name, "x") == 0)
+ return Str::toStr(X());
+ if (strcasecmp(name, "y") == 0)
+ return Str::toStr(Y());
+ if (strcasecmp(name, "width") == 0)
+ return Str::toStr(Width());
+ if (strcasecmp(name, "height") == 0)
+ return Str::toStr(Height());
+ }
+
+ status = fail;
+
+ return 0;
+}
+
+//***************************************************************************
+// Music Variable
+//***************************************************************************
+
+const char* cDisplayItem::musicVariable(const char* group, const char* var,
+ const char* fmt, int& status)
+{
+ static char buf[1000+TB];
+
+ if (strcasecmp(var, "Track") == 0)
+ return formatString(vdrStatus->_music.track(), fmt, buf, sizeof(buf));
+ else if (strcasecmp(var, "Artist") == 0)
+ return formatString(vdrStatus->_music.artist.c_str(), fmt, buf, sizeof(buf));
+ else if (strcasecmp(var, "Album") == 0)
+ return formatString(vdrStatus->_music.album.c_str(), fmt, buf, sizeof(buf));
+ else if (strcasecmp(var, "Genre") == 0)
+ return vdrStatus->_music.genre.c_str();
+ else if (strcasecmp(var, "Year") == 0)
+ return vdrStatus->_music.year.c_str();
+ else if (strcasecmp(var, "Filename") == 0)
+ return formatString(vdrStatus->_music.filename.c_str(), fmt, buf, sizeof(buf));
+ else if (strcasecmp(var, "Comment") == 0)
+ return vdrStatus->_music.comment.c_str();
+ else if (strcasecmp(var, "Frequence") == 0)
+ return Str::toStr(vdrStatus->_music.frequence/1000);
+ else if (strcasecmp(var, "Bitrate") == 0)
+ return Str::toStr(vdrStatus->_music.bitrate/1000);
+ else if (strcasecmp(var, "StereoMode") == 0)
+ return vdrStatus->_music.smode.c_str();
+ else if (strcasecmp(var, "Index") == 0)
+ return Str::toStr(vdrStatus->_music.index);
+ else if (strcasecmp(var, "Count") == 0)
+ return Str::toStr(vdrStatus->_music.cnt);
+ else if (strcasecmp(var, "CurrentTrack") == 0)
+ return vdrStatus->_music.currentTrack.c_str();
+ else if (strcasecmp(var, "PlayStatus") == 0)
+ return vdrStatus->_music.status.c_str();
+ if (strcasecmp(var, "CoverName") == 0)
+ return vdrStatus->_coverPath.c_str();
+ else if (strcasecmp(var, "Rating") == 0)
+ return Str::toStr(vdrStatus->_music.rating);
+ else if (strcasecmp(var, "Loop") == 0)
+ return Str::toStr(vdrStatus->_music.loop);
+ else if (strcasecmp(var, "Timer") == 0)
+ return Str::toStr(vdrStatus->_music.timer);
+ else if (strcasecmp(var, "Copy") == 0)
+ return Str::toStr(vdrStatus->_music.copy);
+ else if (strcasecmp(var, "Lyrics") == 0)
+ return Str::toStr(vdrStatus->_music.lyrics);
+ else if (strcasecmp(var, "Shuffle") == 0)
+ return Str::toStr(vdrStatus->_music.shuffle);
+ else if (strcasecmp(var, "Shutdown") == 0)
+ return Str::toStr(vdrStatus->_music.shutdown);
+ else if (strcasecmp(var, "Recording") == 0)
+ return Str::toStr(vdrStatus->_music.recording);
+
+ else if (strcasecmp(var, "ButtonRed") == 0)
+ return vdrStatus->_music.red.c_str();
+ else if (strcasecmp(var, "ButtonGreen") == 0)
+ return vdrStatus->_music.green.c_str();
+ else if (strcasecmp(var, "ButtonYellow") == 0)
+ return vdrStatus->_music.yellow.c_str();
+ else if (strcasecmp(var, "ButtonBlue") == 0)
+ return vdrStatus->_music.blue.c_str();
+
+ status = fail;
+
+ return 0;
+}