summaryrefslogtreecommitdiff
path: root/display.c
diff options
context:
space:
mode:
Diffstat (limited to 'display.c')
-rw-r--r--display.c2317
1 files changed, 311 insertions, 2006 deletions
diff --git a/display.c b/display.c
index 49ddbb4..54c93f1 100644
--- a/display.c
+++ b/display.c
@@ -7,18 +7,17 @@
* to the COPYING file distributed with this package.
*
* (c) 2001-2004 Carsten Siebholz <c.siebholz AT t-online.de>
- * (c) 2004 Andreas Regel <andreas.regel AT powarman.de>
+ * (c) 2004-2010 Andreas Regel <andreas.regel AT powarman.de>
+ * (c) 2010-2012 Wolfgang Astleitner <mrwastl AT users sourceforge net>
*/
-#include <ctype.h>
-#include <unistd.h>
-#include <sys/io.h>
-#include <sys/time.h>
+#include <stdlib.h>
#include <algorithm>
#include <glcddrivers/config.h>
#include <glcddrivers/drivers.h>
+#include <glcdskin/parser.h>
#include "display.h"
#include "global.h"
@@ -28,1992 +27,481 @@
#include <vdr/tools.h>
#include <vdr/menu.h>
-#include <vdr/plugin.h>
-
-#include "compat.h"
-
-#ifdef USE_WAREAGLEICON
-#include <vdr/iconpatch.h>
-#endif
-
-#define MAXLINES_MSG 4
-#define MAXLINES_TEXT 16
-#define FILENAME_EXTERNAL_TRIGGERED_SYMBOLS "/tmp/graphlcd_symbols"
-
-// tiny: 0..48
-#define MINY_T 0
-#define MAXY_T 48
-
-// small: 49..61
-#define MINY_S (MAXY_T+1)
-#define MAXY_S 61
-
-// medium: 62..127
-#define MINY_M (MAXY_S+1)
-#define MAXY_M 127
-
-// large: 128..
-#define MINY_L (MAXY_M+1)
-#define MAXY_L 9999
-
-
-
-int FRAME_SPACE_X;
-int FRAME_SPACE_XB;
-int FRAME_SPACE_Y;
-int FRAME_SPACE_YB;
-int TEXT_OFFSET_X;
-int TEXT_OFFSET_Y_TIME;
-int TEXT_OFFSET_Y_CHANNEL;
-int TEXT_OFFSET_Y_TITLE;
-int SYMBOL_SPACE;
-int TIMEBAR_HEIGHT;
-
+#include <vdr/remote.h>
cGraphLCDDisplay::cGraphLCDDisplay()
: cThread("glcd_display"),
- update(false),
- active(false),
mLcd(NULL),
- bitmap(NULL),
- GraphLCDState(NULL)
+ mScreen(NULL),
+ mSkin(NULL),
+ mSkinConfig(NULL),
+ mGraphLCDState(NULL)
{
- cfgDir = "";
- fontDir = "";
- logoDir = "";
-
- CurrTime = time(NULL);
- LastTime = CurrTime-58;
- CurrTimeval.tv_sec = 0;
- CurrTimeval.tv_usec = 0;
- timerclear(&UpdateAt);
- LastTimeCheckSym = CurrTime;
-
- State = Normal;
- LastState = Normal;
-
- menuTop = 0;
- menuCount = 0;
- tabCount = 0;
- for (int i = 0; i < kMaxTabCount; i++)
- tab[i] = 0;
- tabMax[0] = 0;
- tabMax[1] = 66;
- tabMax[2] = 100;
- tabMax[3] = 100;
- tabMax[4] = 100;
- tabMax[5] = 100;
- tabMax[6] = 100;
- tabMax[7] = 100;
- tabMax[8] = 100;
- tabMax[9] = 100;
-
- showVolume = false;
-
- logo = NULL;
- logoList = NULL;
-
- strcpy (szETSymbols, "");
+ mUpdate = false;
+ mUpdateAt = 0;
+ mLastTimeMs = 0;
+
+ mState = StateNormal;
+ mLastState = StateNormal;
+
+ mDisplayMode = DisplayModeNormal;
+ LastTimeDisplayMode = 0;
+
+ mShowVolume = false;
+ mShowAudio = false;
nCurrentBrightness = -1;
LastTimeBrightness = 0;
bBrightnessActive = true;
- LastTimeSA.Set(0); //span
- // convert to UTF-8 internally, if we want to support anything else and not only ISO-8859-1
- conv = new cCharSetConv(cCharSetConv::SystemCharacterTable() ? cCharSetConv::SystemCharacterTable() : "UTF-8", "UTF-8");
-#ifdef USE_WAREAGLEICON
- bIsUTF8 = IsLangUtf8();
- textWithIcons = 0;
-#endif
+ mService = NULL; /* cannot be initialised here (mGraphLCDState not yet available) */
}
cGraphLCDDisplay::~cGraphLCDDisplay()
{
- active = false;
Cancel(3);
- delete GraphLCDState;
- delete bitmap;
- delete logoList;
-
- if (conv) {
- delete conv;
- }
-#ifdef USE_WAREAGLEICON
- if (textWithIcons)
- free(textWithIcons);
-#endif
+ delete mSkin;
+ delete mSkinConfig;
+ delete mScreen;
+ delete mGraphLCDState;
+
+ delete mService;
}
-int cGraphLCDDisplay::Init(GLCD::cDriver * Lcd, const char * CfgDir)
+bool cGraphLCDDisplay::Initialise(GLCD::cDriver * Lcd, const std::string & CfgPath, const std::string & SkinsPath, const std::string & SkinName)
{
- if (!Lcd || !CfgDir)
- return 2;
+ std::string skinsPath;
+
+ if (!Lcd)
+ return false;
mLcd = Lcd;
- cfgDir = CfgDir;
- fontDir = cfgDir + "/fonts";
- logoDir = cfgDir + "/logos";
- logoList = new cGraphLCDLogoList(logoDir.c_str(), cfgDir.c_str());
- if (!logoList)
- {
- esyslog("graphlcd plugin: ERROR out of memory\n");
- return 1;
- }
+ mGraphLCDState = new cGraphLCDState(this);
+ if (!mGraphLCDState)
+ return false;
+
+ // must be initialised before cGraphLCDSkinConfig (else: seg fault)
+ mService = new cGraphLCDService(mGraphLCDState);
+
+ skinsPath = SkinsPath;
+ if (skinsPath == "")
+ skinsPath = CfgPath + "/skins";
- std::string fontListFile = cfgDir + "/fonts.conf";
- if (fontList.Load(fontListFile) == false)
+ mSkinConfig = new cGraphLCDSkinConfig(this, CfgPath, skinsPath, SkinName, mGraphLCDState);
+ if (!mSkinConfig)
{
- esyslog("graphlcd plugin: ERROR: Could not load %s!\n", fontListFile.c_str());
- return 1;
+ esyslog("graphlcd plugin: ERROR creating skin config\n");
+ return false;
}
Start();
- return 0;
+ return true;
}
void cGraphLCDDisplay::Tick(void)
{
- if (GraphLCDState)
- GraphLCDState->Tick();
+ if (mGraphLCDState)
+ mGraphLCDState->Tick();
}
void cGraphLCDDisplay::Action(void)
{
+ std::string skinFileName;
+
if (mLcd->Init() != 0)
{
esyslog("graphlcd plugin: ERROR: Failed initializing display\n");
+ GraphLCDSetup.PluginActive = 0;
+ Cancel(-1); // cancel display thread
return;
}
- bitmap = new GLCD::cBitmap(mLcd->Width(), mLcd->Height());
- if (!bitmap)
+ mScreen = new GLCD::cBitmap(mLcd->Width(), mLcd->Height());
+ if (!mScreen)
{
esyslog("graphlcd plugin: ERROR creating drawing bitmap\n");
return;
}
- largeFont = fontList.GetFont("Large Font");
- if (largeFont == NULL)
- {
- esyslog("graphlcd plugin: ERROR: No \"Large Font\" specified!\n");
- return;
- }
- normalFont = fontList.GetFont("Normal Font");
- if (normalFont == NULL)
- {
- esyslog("graphlcd plugin: ERROR: No \"Normal Font\" specified!\n");
- return;
- }
- smallFont = fontList.GetFont("Small Font");
- if (smallFont == NULL)
+ skinFileName = mSkinConfig->SkinPath() + "/" + mSkinConfig->SkinName() + ".skin";
+ std::string errorString = "";
+ mSkin = GLCD::XmlParse(*mSkinConfig, mSkinConfig->SkinName(), skinFileName, errorString);
+ if (!mSkin)
{
- esyslog("graphlcd plugin: ERROR: No \"Small Font\" specified!\n");
- return;
- }
- symbols = fontList.GetFont("Symbol Font");
- if (symbols == NULL)
- {
- esyslog("graphlcd plugin: ERROR: No \"Symbol Font\" specified!\n");
- return;
- }
+ int skipx = mLcd->Width() >> 3;
+ int skipy = mLcd->Height() >> 3;
- if (bitmap->Width() < 240)
- {
- FRAME_SPACE_X = 0;
- FRAME_SPACE_XB = 1;
- TEXT_OFFSET_X = 2;
- }
- else
- {
- FRAME_SPACE_X = 2;
- FRAME_SPACE_XB = 2;
- TEXT_OFFSET_X = 4;
- }
+ esyslog("graphlcd plugin: ERROR loading skin '%s'\n", mSkinConfig->SkinName().c_str());
- if (bitmap->Height() <= MAXY_T)
- {
- // very small display
- FRAME_SPACE_Y = 0;
- FRAME_SPACE_YB = 1;
- TEXT_OFFSET_Y_TIME = 1;
- TEXT_OFFSET_Y_CHANNEL = 1;
- TEXT_OFFSET_Y_TITLE = 1;
- SYMBOL_SPACE = 1;
- TIMEBAR_HEIGHT = 3;
- }
- else if (bitmap->Height() <= MAXY_S)
- {
- // small display
- FRAME_SPACE_Y = 0;
- FRAME_SPACE_YB = 1;
- TEXT_OFFSET_Y_TIME = 1;
- TEXT_OFFSET_Y_CHANNEL = 3;
- TEXT_OFFSET_Y_TITLE = 1;
- SYMBOL_SPACE = 1;
- TIMEBAR_HEIGHT = 3;
- }
- else if (bitmap->Height() <= MAXY_M)
- {
- // medium display
- FRAME_SPACE_Y = 0;
- FRAME_SPACE_YB = 1;
- TEXT_OFFSET_Y_TIME = 1;
- TEXT_OFFSET_Y_CHANNEL = 3;
- TEXT_OFFSET_Y_TITLE = 3;
- SYMBOL_SPACE = 1;
- TIMEBAR_HEIGHT = 3;
- }
- else
- {
- // large display
- FRAME_SPACE_Y = 2;
- FRAME_SPACE_YB = 2;
- TEXT_OFFSET_Y_TIME = 2;
- TEXT_OFFSET_Y_CHANNEL = 5;
- TEXT_OFFSET_Y_TITLE = 5;
- SYMBOL_SPACE = 2;
- TIMEBAR_HEIGHT = 5;
- }
+ mLcd->Clear();
+ // clear the screen with a filled rectangle using a defined colour to guarantee visible text or 'X'
+#ifdef GRAPHLCD_CBITMAP_ARGB
+ mScreen->DrawRectangle(0, 0, mLcd->Width()-1, mLcd->Height()-1, GLCD::cColor::Black, true);
+#else
+ mScreen->DrawRectangle(0, 0, mLcd->Width()-1, mLcd->Height()-1, GLCD::clrBlack, true);
+#endif
- GraphLCDState = new cGraphLCDState(this);
- if (!GraphLCDState)
+ GLCD::cFont * font = new GLCD::cFont();
+ if ( font->LoadFNT( mSkinConfig->FontPath() + "/" + "f8n.fnt") ) {
+ std::vector <std::string> lines;
+ font->WrapText(mLcd->Width()-10, mLcd->Height()-1, errorString, lines);
+ int lh = font->LineHeight();
+ for (size_t i = 0; i < lines.size(); i++) {
+#ifdef GRAPHLCD_CBITMAP_ARGB
+ mScreen->DrawText(3, 1+i*lh, mLcd->Width()-1, lines[i], font, GLCD::cColor::White);
+#else
+ mScreen->DrawText(3, 1+i*lh, mLcd->Width()-1, lines[i], font, GLCD::clrWhite);
+#endif
+ }
+ } else {
+ // draw an 'X' to inform the user that there was a problem with loading the skin
+ // (better than just leaving an empty screen ...)
+#ifdef GRAPHLCD_CBITMAP_ARGB
+ mScreen->DrawLine(skipx, skipy, mLcd->Width()-1-skipx, mLcd->Height()-1-skipy, GLCD::cColor::White);
+ mScreen->DrawLine(mLcd->Width()-1-skipx, skipy, skipx, mLcd->Height()-1-skipy, GLCD::cColor::White);
+#else
+ mScreen->DrawLine(skipx, skipy, mLcd->Width()-1-skipx, mLcd->Height()-1-skipy, GLCD::clrWhite);
+ mScreen->DrawLine(mLcd->Width()-1-skipx, skipy, skipx, mLcd->Height()-1-skipy, GLCD::clrWhite);
+#endif
+ }
+#ifdef GRAPHLCD_CBITMAP_ARGB
+ mLcd->SetScreen(mScreen->Data(), mScreen->Width(), mScreen->Height());
+#else
+ mLcd->SetScreen(mScreen->Data(), mScreen->Width(), mScreen->Height(), mScreen->LineSize());
+#endif
+ mLcd->Refresh(true);
return;
+ }
+ mSkin->SetBaseSize(mScreen->Width(), mScreen->Height());
+ mLcd->Clear();
mLcd->Refresh(true);
- active = true;
- update = true;
- while (active)
+ mUpdate = true;
+
+ uint64_t lastEventMs = 0;
+#define MIN_EVENT_DELAY 500
+
+ while (Running())
{
if (GraphLCDSetup.PluginActive)
{
- CurrTime = time(NULL);
+ uint64_t currTimeMs = cTimeMs::Now();
+ GLCD::cSkinDisplay * display = NULL;
- if (timerisset(&UpdateAt))
+ if (mUpdateAt != 0)
{
// timed Update enabled
- if (gettimeofday(&CurrTimeval, NULL) == 0)
+ if (currTimeMs > mUpdateAt)
{
- // get current time
- if (CurrTimeval.tv_sec > UpdateAt.tv_sec)
- {
- timerclear(&UpdateAt);
- update = true;
- }
- else if (CurrTimeval.tv_sec == UpdateAt.tv_sec &&
- CurrTimeval.tv_usec > UpdateAt.tv_usec)
- {
- timerclear(&UpdateAt);
- update = true;
- }
- }
- }
- if (GraphLCDSetup.ShowVolume && !update && showVolume)
- {
- if (TimeMs() - GraphLCDState->GetVolumeState().lastChange > 2000)
- {
- update = true;
- showVolume = false;
+ mUpdateAt = 0;
+ mUpdate = true;
}
}
- SetBrightness();
-
- switch (State)
+ if (GraphLCDSetup.ShowVolume)
{
- case Normal:
- // check and update external triggered symbols
- if (GraphLCDSetup.ShowETSymbols)
+ tVolumeState volume;
+ volume = mGraphLCDState->GetVolumeState();
+
+ if (volume.lastChange > 0)
+ {
+ if (!mShowVolume)
{
- if (CurrTime != LastTimeCheckSym)
+ if (currTimeMs - volume.lastChange < 2000)
{
- update |= CheckAndUpdateSymbols();
- LastTimeCheckSym = CurrTime;
+ mShowVolume = true;
+ mUpdate = true;
}
}
-
+ else
{
- std::vector<cScroller>::iterator it;
- for (it = scroller.begin(); it != scroller.end(); it++)
+ if (currTimeMs - volume.lastChange > 2000)
{
- if (it->NeedsUpdate())
- update = true;
+ mShowVolume = false;
+ mUpdate = true;
}
}
+ }
+ }
- // update Display if animated Logo is present, and an update is necessary
- if (!update && IsLogoActive() && logo->Count() > 1 &&
- (TimeMs() - logo->LastChange() >= logo->Delay()))
- {
- update = true;
- }
-
- // update Display every minute or due to an update
- if (CurrTime/60 != LastTime/60 || update)
- {
- timerclear(&UpdateAt);
- update = false;
-
- bitmap->Clear();
- DisplayTime();
- DisplayLogo();
- DisplayChannel();
- DisplaySymbols();
- DisplayProgramme();
- DisplayVolume();
- DisplayMessage();
- mLcd->SetScreen(bitmap->Data(), bitmap->Width(), bitmap->Height(), bitmap->LineSize());
- mLcd->Refresh(false);
- LastTime = CurrTime;
- }
- else
- {
-#if VDRVERSNUM < 10314
- usleep(100000);
-#else
- cCondWait::SleepMs(100);
-#endif
- }
- break;
+ if (GraphLCDSetup.ShowMenu)
+ {
+ tAudioState audio;
+ audio = mGraphLCDState->GetAudioState();
- case Replay:
+ if (audio.tracks.size() == 0) {
+ mShowAudio = false;
+ } else
+ if (audio.lastChange > 0)
{
- tReplayState replay = GraphLCDState->GetReplayState();
- if (replay.control)
+ if (!mShowAudio)
{
+ if (currTimeMs - audio.lastChange < 5000)
{
- update = false;
- std::vector<cScroller>::iterator it;
- for (it = scroller.begin(); it != scroller.end(); it++)
- {
- if (it->NeedsUpdate())
- update = true;
- }
- }
- // update Display if animated Logo is present, and an update is necessary
- if (!update && IsLogoActive() && logo->Count() > 1 &&
- TimeMs() - logo->LastChange() >= logo->Delay())
- {
- update = true;
- }
-
- if ( LastTimeSA.TimedOut() ) //span
- {
- update = true;
- LastTimeSA.Set(1000);
- }
-
- // update Display every second or due to an update
- if (CurrTime != LastTime || update)
- {
- // but only, if something has changed
-#if VDRVERSNUM >= 10701
- if (replay.total / replay.framesPerSecond != replay.totalLast / replay.framesPerSecond ||
- replay.current / replay.framesPerSecond != replay.currentLast / replay.framesPerSecond ||
- CurrTime/60 != LastTime/60 ||
- update)
-#else
- if (replay.total / FRAMESPERSEC != replay.totalLast / FRAMESPERSEC ||
- replay.current / FRAMESPERSEC != replay.currentLast / FRAMESPERSEC ||
- CurrTime/60 != LastTime/60 ||
- update)
-#endif
- {
- timerclear(&UpdateAt);
- update = false;
- bitmap->Clear();
- DisplayTime();
- DisplayLogo();
- DisplayReplay(replay);
- //DisplaySymbols();
- DisplayVolume();
- DisplayMessage();
- mLcd->SetScreen(bitmap->Data(), bitmap->Width(), bitmap->Height(), bitmap->LineSize());
- mLcd->Refresh(false);
- LastTime = CurrTime;
- }
- else
- {
-#if VDRVERSNUM < 10314
- usleep(100000);
-#else
- cCondWait::SleepMs(100);
-#endif
- }
- }
- else
- {
-#if VDRVERSNUM < 10314
- usleep(100000);
-#else
- cCondWait::SleepMs(100);
-#endif
+ mShowAudio = true;
+ mUpdate = true;
}
}
else
{
- State = Normal;
- Update();
- }
- }
- break;
-
- case Menu:
- if (GraphLCDSetup.ShowMenu)
- {
- // update Display every minute or due to an update
- if (CurrTime/60 != LastTime/60 || update)
+ if (currTimeMs - audio.lastChange > 5000)
{
- timerclear(&UpdateAt);
- update = false;
-
- bitmap->Clear();
- DisplayTime();
- DisplayMenu();
- DisplayTextItem();
- DisplayVolume();
- DisplayMessage();
- DisplayColorButtons();
- mLcd->SetScreen(bitmap->Data(), bitmap->Width(), bitmap->Height(), bitmap->LineSize());
- mLcd->Refresh(false);
- LastTime = CurrTime;
+ mShowAudio = false;
+ mUpdate = true;
}
- else
- {
-#if VDRVERSNUM < 10314
- usleep(100000);
-#else
- cCondWait::SleepMs(100);
-#endif
- }
- }
- else
- {
- //GraphLCDState.OsdClear();
-
- State = LastState;
- // activate delayed Update
-#if VDRVERSNUM < 10314
- usleep(100000);
-#else
- cCondWait::SleepMs(100);
-#endif
}
- break;
-
- default:
- break;
- }
- }
- else
- {
-#if VDRVERSNUM < 10314
- usleep(100000);
-#else
- cCondWait::SleepMs(100);
-#endif
- }
- }
-}
-
-void cGraphLCDDisplay::SetChannel(int ChannelNumber)
-{
- if (ChannelNumber == 0)
- return;
-
- mutex.Lock();
- cChannel * ch = Channels.GetByNumber(ChannelNumber);
- if (GraphLCDSetup.ShowLogo)
- {
- ePicType picType;
-
- switch (GraphLCDSetup.ShowLogo)
- {
- case 1: // auto
- if (bitmap->Height() <= MAXY_M)
- picType = ptLogoMedium;
- else
- picType = ptLogoLarge;
- break;
- case 2: // medium
- picType = ptLogoMedium;
- break;
- case 3: // large
- picType = ptLogoLarge;
- break;
- default: // should not happen at the moment !!
- picType = ptLogoSmall;
- break;
- }
-#if VDRVERSNUM >= 10300
- char strTmp[64];
- strcpy(strTmp, (const char *) ch->GetChannelID().ToString());
- char * strId = strstr(strTmp, "-") + 1;
- logo = logoList->GetLogo(strId, picType);
-#else
- char strId[16];
- sprintf(strId, "%d", ch->Sid());
- logo = logoList->GetLogo(strId, picType);
-#endif
- if (logo)
- logo->First(TimeMs());
- }
- else
- {
- logo = NULL;
- }
- bBrightnessActive = true;
- Update();
- mutex.Unlock();
-}
-
-void cGraphLCDDisplay::SetClear()
-{
- mutex.Lock();
-
- textItemLines.clear();
- textItemTop = 0;
- tabCount = 0;
- for (int i = 0; i < kMaxTabCount; i++)
- tab[i] = 0;
-
- mutex.Unlock();
-
- if (State == Menu)
- {
- State = LastState;
- // activate delayed Update
- UpdateIn(100000);
- }
- else
- {
- Update();
- }
-}
-
-void cGraphLCDDisplay::SetOsdTitle()
-{
- UpdateIn(0); // stop delayed Update
- mutex.Lock();
- if (State != Menu)
- {
- menuTop = 0;
- LastState = State;
- State = Menu;
- }
- mutex.Unlock();
- // activate delayed Update
- UpdateIn(100000);
-}
-
-void cGraphLCDDisplay::SetOsdItem(const char * Text)
-{
- int iAT, t;
- std::string str;
- std::string::size_type pos1, pos2;
-
- mutex.Lock();
-
- UpdateIn(0); // stop delayed Update
- str = Text;
- pos1 = 0;
- pos2 = str.find('\t');
- iAT = 0;
- while (pos1 < str.length() && pos2 != std::string::npos)
- {
- iAT++;
- t = std::min(normalFont->Width(str.substr(pos1), pos2 - pos1), (tabMax[iAT] * bitmap->Width()) / 100);
- tab[iAT] = std::max(tab[iAT], t);
- tabCount = std::max(tabCount, iAT);
- pos1 = pos2 + 1;
- pos2 = str.find('\t', pos1);
- }
- mutex.Unlock();
-}
-
-void cGraphLCDDisplay::SetOsdCurrentItem()
-{
- UpdateIn(100000); //XXX
-}
-
-void cGraphLCDDisplay::Replaying(bool starting, eReplayMode replayMode)
-{
- if (starting)
- {
- if (State != Menu)
- {
- State = Replay;
- }
- else
- {
- LastState = Replay;
- }
- if (GraphLCDSetup.ReplayLogo)
- {
- ePicType picType;
-
- switch (GraphLCDSetup.ReplayLogo)
- {
- case 1: // auto
- if (bitmap->Height() <= MAXY_M)
- picType = ptLogoMedium;
- else
- picType = ptLogoLarge;
- break;
- case 2: // medium
- picType = ptLogoMedium;
- break;
- case 3: // large
- picType = ptLogoLarge;
- break;
- default: // should not happen at the moment !!
- picType = ptLogoSmall;
- break;
- }
- switch (replayMode)
- {
- default:
- case eReplayNormal :
- logo = logoList->GetLogo("REPLAY-VDR", picType);break;
- case eReplayMusic :
- logo = logoList->GetLogo("REPLAY-MUSIC", picType);break;
- case eReplayDVD :
- logo = logoList->GetLogo("REPLAY-DVD", picType);break;
- case eReplayFile :
- logo = logoList->GetLogo("REPLAY-FILE", picType);break;
- case eReplayImage :
- logo = logoList->GetLogo("REPLAY-IMAGE", picType);break;
- case eReplayAudioCD:
- logo = logoList->GetLogo("REPLAY-AUDIOCD", picType);break;
- }
- if (logo)
- logo->First(TimeMs());
- }
- else
- {
- logo = NULL;
- }
- }
- else
- {
- if (State != Menu)
- {
- State = Normal;
- }
- else
- {
- LastState = Normal;
- }
- }
- bBrightnessActive = true;
- Update();
-}
-
-void cGraphLCDDisplay::SetOsdTextItem(const char * Text, bool Scroll)
-{
- static const char * lastText = NULL;
- tOsdState osd;
-
- osd = GraphLCDState->GetOsdState();
- mutex.Lock();
- if (Text)
- {
- if (osd.textItem.length() == 0)
- lastText = NULL;
- int maxTextLen = bitmap->Width() - 2 * FRAME_SPACE_X - 2 * TEXT_OFFSET_X;
- normalFont->WrapText(maxTextLen, 0, osd.textItem, textItemLines);
- textItemLines.push_back("");
- if (lastText != Text)
- {
- lastText = Text;
- textItemTop = 0;
- }
- }
- else
- {
- if (Scroll)
- {
- if (textItemTop > 0)
- textItemTop--;
- }
- else
- {
- if (textItemTop < (int) textItemLines.size() - 2)
- textItemTop++;
- }
- }
- mutex.Unlock();
- UpdateIn(100000);
-}
-
-void cGraphLCDDisplay::Update()
-{
- update = true;
-}
-
-void cGraphLCDDisplay::Clear()
-{
- bitmap->Clear();
- mLcd->SetScreen(bitmap->Data(), bitmap->Width(), bitmap->Height(), bitmap->LineSize());
- mLcd->Refresh(false);
-}
-
-void cGraphLCDDisplay::DisplayTime()
-{
- static char buffer[32];
- static char month[16];
- int FrameWidth, TextLen, yPos;
- struct tm tm_r;
-
- if (GraphLCDSetup.ShowDateTime == 1 ||
- (GraphLCDSetup.ShowDateTime == 2 && State != Menu))
- {
- FrameWidth = std::max(bitmap->Width() - 2 * FRAME_SPACE_X, 1);
- if (State == Normal || State == Replay)
- {
- if (IsLogoActive()) // Logo enabled & available
- {
- FrameWidth = std::max(FrameWidth - FRAME_SPACE_XB - logo->Width() - 2, (unsigned int) 1);
- }
- if (bitmap->Height() <= MAXY_M)
- {
- // tiny, small & medium display
- if (IsSymbolsActive()) // Symbols enabled
- {
- FrameWidth = std::max(FrameWidth - FRAME_SPACE_XB - symbols->TotalWidth(), 1);
}
}
- }
- yPos = FRAME_SPACE_Y;
-
- // draw Rectangle
- bitmap->DrawRoundRectangle(FRAME_SPACE_X, yPos,
- FRAME_SPACE_X + FrameWidth - 1,
- yPos + normalFont->TotalHeight() + 2 * TEXT_OFFSET_Y_TIME - 1,
- GLCD::clrBlack, true, (TEXT_OFFSET_Y_TIME >= 2) ? 4 : 1);
-
- if (CurrTime == 0)
- time(&CurrTime);
- tm * tm = localtime_r(&CurrTime, &tm_r);
-
- const char *amonth = tr("JanFebMarAprMayJunJulAugSepOctNovDec");
- amonth += Utf8SymChars(amonth, tm->tm_mon * 3);
- strn0cpy(month, amonth, min(Utf8SymChars(amonth, 3) + 1, int(sizeof(month))));
- snprintf(buffer, sizeof(buffer), "%s %2d.%s %d:%02d", (const char *) WeekDayName(tm->tm_wday), tm->tm_mday, Convert(month), tm->tm_hour, tm->tm_min);
- TextLen = normalFont->Width(buffer);
- if (TextLen > std::max(FrameWidth - 2 * TEXT_OFFSET_X, 1))
- {
- snprintf(buffer, sizeof(buffer), "%d.%s %d:%02d", tm->tm_mday, Convert(month), tm->tm_hour, tm->tm_min);
- TextLen = normalFont->Width(buffer);
- }
-
- if (TextLen > std::max(FrameWidth - 2 * TEXT_OFFSET_X, 1))
- {
- snprintf(buffer, sizeof(buffer), "%d.%d. %d:%02d", tm->tm_mday, tm->tm_mon+1, tm->tm_hour, tm->tm_min);
- TextLen = normalFont->Width(buffer);
- }
+ /* display mode (normal or interactive): reset after 10 secs if not normal */
+ if ( (mDisplayMode != DisplayModeNormal) && ( (uint32_t)(currTimeMs - LastTimeDisplayMode) > (uint32_t)(10000)) ) {
+ mDisplayMode = DisplayModeNormal;
+ LastTimeDisplayMode = currTimeMs;
+ mUpdate = true;
+ }
- if (TextLen > std::max(FrameWidth - 2 * TEXT_OFFSET_X, 1))
- {
- snprintf(buffer, sizeof(buffer), "%d:%02d", tm->tm_hour, tm->tm_min);
- TextLen = normalFont->Width(buffer);
- }
+ if (mState == StateNormal)
+ display = mSkin->GetDisplay("normal");
+ else if (mState == StateReplay)
+ display = mSkin->GetDisplay("replay");
+ else if (mState == StateMenu)
+ display = mSkin->GetDisplay("menu");
+ if (display && display->NeedsUpdate(currTimeMs ) )
+ mUpdate = true;
- if (TextLen < std::max(FrameWidth - 2 * TEXT_OFFSET_X, 1))
- {
- bitmap->DrawText(FRAME_SPACE_X + FrameWidth - TextLen - TEXT_OFFSET_X,
- yPos + TEXT_OFFSET_Y_TIME,
- FRAME_SPACE_X + FrameWidth - 1,
- buffer, normalFont, GLCD::clrWhite);
- }
- else
- {
- bitmap->DrawText(FRAME_SPACE_X + TEXT_OFFSET_X,
- yPos + TEXT_OFFSET_Y_TIME,
- FRAME_SPACE_X + FrameWidth - 1,
- buffer, normalFont, GLCD::clrWhite);
- }
- }
-}
-void cGraphLCDDisplay::DisplayChannel()
-{
- int FrameWidth, yPos;
- tChannelState channel;
- const char * pszTmp1;
-
- channel = GraphLCDState->GetChannelState();
- if (GraphLCDSetup.ShowChannel)
- {
- FrameWidth = std::max(bitmap->Width() - 2 * FRAME_SPACE_X, 1);
- if (State == Normal)
- {
- if (IsLogoActive()) // Logo enabled & available
- {
- FrameWidth = std::max(FrameWidth - FRAME_SPACE_XB - logo->Width() - 2, (unsigned int) 1);
- }
- if (bitmap->Height() <= MAXY_M)
+ // update Display every minute
+ if (mState == StateNormal && (currTimeMs/60000 != mLastTimeMs/60000))
{
- // tiny, small & medium display
- if (IsSymbolsActive()) // Symbols enabled
- {
- FrameWidth = std::max(FrameWidth - FRAME_SPACE_XB - symbols->TotalWidth(), 1);
- }
+ mUpdate = true;
}
- }
-
- if (GraphLCDSetup.ShowDateTime == 1 ||
- (GraphLCDSetup.ShowDateTime == 2 && State != Menu))
- {
- yPos = FRAME_SPACE_Y + normalFont->TotalHeight() + 2 * TEXT_OFFSET_Y_TIME + FRAME_SPACE_YB;
- if (bitmap->Height() >= MINY_L)
+ // update Display every second in replay state
+ if (mState == StateReplay && (currTimeMs/1000 != mLastTimeMs/1000))
{
- // align bottom border with logo
- if (IsLogoActive()) // Logo enabled & available
- {
- yPos += std::max((unsigned int) 0, FRAME_SPACE_Y + logo->Height() + 2 - yPos -
- (normalFont->TotalHeight() + 2 * TEXT_OFFSET_Y_CHANNEL));
- }
+ mUpdate = true;
}
- }
- else
- {
- yPos = FRAME_SPACE_Y;
- }
-
- // draw Rectangle
- bitmap->DrawRoundRectangle(FRAME_SPACE_X, yPos,
- FRAME_SPACE_X + FrameWidth - 1,
- yPos + normalFont->TotalHeight() + 2 * TEXT_OFFSET_Y_CHANNEL - 1,
- GLCD::clrBlack, true, (TEXT_OFFSET_Y_CHANNEL >= 4) ? 4 : 1);
-
- if (channel.strTmp.length() > 0)
- {
- pszTmp1 = Convert(channel.strTmp.c_str());
- bitmap->DrawText(FRAME_SPACE_X + TEXT_OFFSET_X,
- yPos + TEXT_OFFSET_Y_CHANNEL,
- FRAME_SPACE_X + FrameWidth - 1,
- pszTmp1, normalFont, GLCD::clrWhite);
- }
- else if (channel.str.length() > 0)
- {
- pszTmp1 = Convert(channel.str.c_str());
- bitmap->DrawText(FRAME_SPACE_X + TEXT_OFFSET_X,
- yPos + TEXT_OFFSET_Y_CHANNEL,
- FRAME_SPACE_X + FrameWidth - 1,
- pszTmp1, normalFont, GLCD::clrWhite);
- }
- }
-}
-bool cGraphLCDDisplay::IsLogoActive() const
-{
- if ((State==Normal && GraphLCDSetup.ShowLogo) ||
- (State==Replay && GraphLCDSetup.IdentifyReplayType && GraphLCDSetup.ReplayLogo))
- {
- return logo != NULL;
- }
- return false;
-}
-void cGraphLCDDisplay::DisplayLogo()
-{
- int x;
- int y;
+ bool bActive = bBrightnessActive
+ || (mState == StateMenu)
+ || (GraphLCDSetup.ShowVolume && mShowVolume)
+ || (GraphLCDSetup.ShowMenu && mShowAudio)
+ || (GraphLCDSetup.ShowMessages && mGraphLCDState->ShowMessage())
+ || (GraphLCDSetup.BrightnessDelay == 900);
- if (IsLogoActive())
- {
- if (logo->Count() > 1)
- {
- uint64_t t = TimeMs();
- if (t - logo->LastChange() >= logo->Delay())
+ // update display if BrightnessDelay is exceeded
+ if (bActive && (nCurrentBrightness == GraphLCDSetup.BrightnessActive) &&
+ ((uint32_t)((/*cTimeMs::Now()*/currTimeMs - LastTimeBrightness)) > (uint32_t)(GraphLCDSetup.BrightnessDelay*1000)))
{
- if (!logo->Next(t))
- logo->First(t);
+ mUpdate = true;
}
- }
-
- x = std::max(bitmap->Width() - FRAME_SPACE_X - logo->Width() - 2, (unsigned int) 0);
- y = FRAME_SPACE_Y;
-
- bitmap->DrawRoundRectangle(x, y, x + logo->Width() + 1, y + logo->Height() + 1, GLCD::clrBlack, false, 1);
- bitmap->DrawBitmap(x + 1, y + 1, *logo->GetBitmap(), GLCD::clrBlack);
- }
-}
-
-bool cGraphLCDDisplay::IsSymbolsActive() const
-{
- return GraphLCDSetup.ShowSymbols;
-}
-void cGraphLCDDisplay::DisplaySymbols()
-{
- int yPos = 0;
- int xPos = 0;
- int i;
- tChannelState channel;
- tVolumeState volume;
- tCardState card[MAXDEVICES];
-
- channel = GraphLCDState->GetChannelState();
- for (i = 0; i < MAXDEVICES; i++)
- card[i] = GraphLCDState->GetCardState(i);
- volume = GraphLCDState->GetVolumeState();
-
- if (IsSymbolsActive())
- {
- cChannel * ch = Channels.GetByNumber(channel.number);
- if (ch)
- {
- if (bitmap->Height() <= MAXY_M) // medium display
+ // external service changed (check each 1/10th second)
+ if ( (currTimeMs/100 != mLastTimeMs/100) && mService->NeedsUpdate(currTimeMs))
{
- yPos = FRAME_SPACE_Y;
- xPos = bitmap->Width() - FRAME_SPACE_X - symbols->TotalWidth();
-
- if (IsLogoActive())
- {
- xPos -= FRAME_SPACE_XB + logo->Width() + 2;
- }
-
- if (GraphLCDSetup.ShowSymbols == 1) // normal/fixed symbols
- {
- // new layout:
- // displays rec symbols for every card and
- // 2chan + dolby have their own symbols
- // user triggered symbols
-
- int yPos2 = 0;
-
- // blank or 2chan or mute
- if (volume.value == 0)
- {
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, 'M', symbols);
- yPos += symbols->Height('S') + SYMBOL_SPACE;
- }
- else if (ch->Apid2())
- {
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, 'A', symbols);
- yPos += symbols->Height('A') + SYMBOL_SPACE;
- }
- else
- {
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, ' ', symbols);
- yPos += symbols->Height(' ') + SYMBOL_SPACE;
- }
-
- // blank or dolby
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, ch->Dpid1() ? 'D' : ' ', symbols);
- yPos += symbols->Height(ch->Dpid1() ? 'D' : ' ') + SYMBOL_SPACE;
-
- // blank or teletext
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, ch->Tpid() ? 'T' : ' ', symbols);
- yPos += symbols->Height(ch->Tpid() ? 'T' : ' ') + SYMBOL_SPACE;
-
- // blank or crypt
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, ch->Ca() ? 'C' : ' ', symbols);
- yPos += symbols->Height(ch->Tpid() ? 'C' : ' ') + SYMBOL_SPACE;
-
- // show REC symbols at the right border below the logo
- yPos2 = yPos;
- yPos = FRAME_SPACE_Y;
- if (GraphLCDSetup.ShowDateTime == 1 ||
- (GraphLCDSetup.ShowDateTime == 2 && State != Menu))
- {
- yPos += normalFont->TotalAscent() + 2 * TEXT_OFFSET_Y_TIME + FRAME_SPACE_YB;
- }
- if (GraphLCDSetup.ShowChannel)
- {
- yPos += normalFont->TotalAscent() + 2 * TEXT_OFFSET_Y_CHANNEL + FRAME_SPACE_YB;
- }
- if (IsLogoActive())
- {
- yPos = std::max((unsigned int) yPos, FRAME_SPACE_Y + logo->Height() + 2 + FRAME_SPACE_YB);
- }
-
- yPos = std::max(yPos, yPos2);
- xPos = bitmap->Width() - FRAME_SPACE_X + SYMBOL_SPACE;
- for (i = LCDMAXCARDS - 1; i >= 0; i--)
- {
- if (card[i].recordingCount > 0)
- {
- xPos -= symbols->Width(49 + i) + SYMBOL_SPACE;
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, 49 + i, symbols);
- }
- }
-
- // show external triggered symbols
- if (GraphLCDSetup.ShowETSymbols && strlen(szETSymbols) > 0)
- {
- for (i = strlen(szETSymbols) - 1; i >= 0; i--)
- {
- xPos -= symbols->Width(szETSymbols[i]) + SYMBOL_SPACE;
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, szETSymbols[i], symbols);
+ mUpdate = true;
+ }
+
+
+ // check event
+ GLCD::cGLCDEvent * ev = mSkin->Config().GetDriver()->GetEvent();
+ if (ev && display && ((uint32_t)(currTimeMs-lastEventMs) > (uint32_t)(MIN_EVENT_DELAY) )) {
+ std::string rv = "";
+
+ if ( (rv = display->CheckAction(ev) ) != "") {
+ if (rv.substr(0,4) == "Key.") {
+ cRemote::Put(cKey::FromString(rv.substr(4).c_str()), true);
+ LastTimeDisplayMode = currTimeMs; /* if interactive mode: extend it */
+ } else if (rv.substr(0,5) == "Mode.") {
+ if (rv.substr(5) == "Interactive") {
+ mDisplayMode = DisplayModeInteractive;
+ LastTimeDisplayMode = currTimeMs;
+ } else if (rv.substr(5) == "Normal") {
+ mDisplayMode = DisplayModeNormal;
+ LastTimeDisplayMode = currTimeMs;
}
+ mUpdate = true;
}
- }
- else // compressed symbols
- {
- // old layout:
- // displays only 1 rec symbol and
- // a combined 2chan + dolby symbol
-
- // blank or teletext
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, ch->Tpid() ? 'T' : ' ', symbols);
- yPos += symbols->Height(ch->Tpid() ? 'T' : ' ') + SYMBOL_SPACE;
-
- // blank or crypt
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, ch->Ca() ? 'C' : ' ', symbols);
- yPos += symbols->Height(ch->Tpid() ? 'C' : ' ') + SYMBOL_SPACE;
-
- // blank, 2chan, dolby or combined symbol
- if (volume.value == 0)
- {
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, 'M', symbols);
- yPos += symbols->Height('S') + SYMBOL_SPACE;
- }
- else if (ch->Apid2() && ch->Dpid1())
- {
- // if Apid2 and Dpid1 are set then use combined symbol
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, 'B', symbols);
- yPos += symbols->Height('B') + SYMBOL_SPACE;
- }
- else if (ch->Apid2())
- {
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, 'A', symbols);
- yPos += symbols->Height('A') + SYMBOL_SPACE;
- }
- else if (ch->Dpid1())
- {
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, 'D', symbols);
- yPos += symbols->Height('D') + SYMBOL_SPACE;
- }
- else
- {
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, ' ', symbols);
- yPos += symbols->Height(' ') + SYMBOL_SPACE;
- }
-
- // blank or rec
- if (cRecordControls::Active())
- {
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, '1', symbols);
- }
- else
- {
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, ' ', symbols);
- }
+ lastEventMs = currTimeMs;
}
}
- else // large display
+
+ if (mUpdate)
{
- yPos = FRAME_SPACE_Y;
- if (GraphLCDSetup.ShowDateTime == 1 ||
- (GraphLCDSetup.ShowDateTime == 2 && State != Menu))
- {
- yPos += normalFont->TotalHeight() + 2 * TEXT_OFFSET_Y_TIME + FRAME_SPACE_YB;
- }
- if (GraphLCDSetup.ShowChannel)
- {
- yPos += normalFont->TotalHeight() + 2 * TEXT_OFFSET_Y_CHANNEL + FRAME_SPACE_YB;
- }
- if (IsLogoActive())
- {
- yPos = std::max((unsigned int) yPos, FRAME_SPACE_Y + logo->Height() + 2 + FRAME_SPACE_YB);
- }
+ mUpdateAt = 0;
+ mUpdate = false;
- xPos = bitmap->Width() - FRAME_SPACE_X - symbols->Width(' ');
+ mGraphLCDState->Update();
- if (GraphLCDSetup.ShowSymbols == 1) // normal/fixed symbols
- {
- // blank or teletext
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, ch->Tpid() ? 'T' : ' ', symbols);
- xPos -= symbols->Width(ch->Tpid() ? 'T' : ' ') + SYMBOL_SPACE;
+ mScreen->Clear(mSkin->GetBackgroundColor());
- // blank or dolby
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, ch->Dpid1() ? 'D' : ' ', symbols);
- xPos -= symbols->Width(ch->Dpid1() ? 'D' : ' ') + SYMBOL_SPACE;
+ mSkin->SetTSEvalTick(currTimeMs);
- if (bitmap->Height() > MAXY_M) // with 128 pixel width only 3 symbols...
- {
- // blank or crypt
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, ch->Ca()? 'C' : ' ', symbols);
- xPos -= symbols->Width(ch->Ca() ? 'C' : ' ') + SYMBOL_SPACE;
- }
+ GLCD::cSkinDisplay * display = NULL;
- // blank or 2chan or mute
- if (volume.value == 0)
- {
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, 'M', symbols);
- xPos -= symbols->Width('S') + SYMBOL_SPACE;
- }
- else if (ch->Apid2())
- {
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, 'A', symbols);
- xPos -= symbols->Width('A') + SYMBOL_SPACE;
- }
- else
- {
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, ' ', symbols);
- xPos -= symbols->Width(' ') + SYMBOL_SPACE;
- }
- }
- else // compressed symbols
+ if (mState == StateNormal)
+ display = mSkin->GetDisplay("normal");
+ else if (mState == StateReplay)
+ display = mSkin->GetDisplay("replay");
+ else if (mState == StateMenu)
+ display = mSkin->GetDisplay("menu");
+ if (display)
+ display->Render(mScreen);
+ if (mShowVolume)
{
- // crypt
- if (ch->Ca())
- {
- xPos -= symbols->Width('C') + SYMBOL_SPACE;
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, 'C', symbols);
- }
-
- // teletext
- if (ch->Tpid())
- {
- xPos -= symbols->Width('T') + SYMBOL_SPACE;
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, 'T', symbols);
- }
-
- // dolby
- if (ch->Dpid1())
- {
- xPos -= symbols->Width('D') + SYMBOL_SPACE;
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, 'D', symbols);
- }
-
- // 2chan
- if (ch->Apid2())
- {
- xPos -= symbols->Width('A') + SYMBOL_SPACE;
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, 'A', symbols);
- }
-
- // mute
- if (volume.value == 0)
- {
- xPos -= symbols->Width('S') + SYMBOL_SPACE;
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, 'M', symbols);
- }
+ display = mSkin->GetDisplay("volume");
+ if (display)
+ display->Render(mScreen);
}
-
- // show REC symbols at the right border of the 'next line'
- xPos = bitmap->Width() - FRAME_SPACE_X + SYMBOL_SPACE;
- yPos += symbols->TotalHeight() + FRAME_SPACE_YB;
- for (i = cDevice::NumDevices() - 1; i >= 0; i--)
+ if (mShowAudio)
{
- // Just display present devices
- xPos -= symbols->Width(49 + i) + SYMBOL_SPACE;
- if (card[i].recordingCount > 0)
- {
- // Show a recording Symbol
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, 49 + i, symbols);
- }
- else
- {
- if (GraphLCDSetup.ShowNotRecording == 1)
- {
- // Do we want an empty frame around not recording card's icons?
- // Show an empty frame instead of the recording symbol
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, ' ', symbols);
- }
- }
+ display = mSkin->GetDisplay("audio");
+ if (display)
+ display->Render(mScreen);
}
-
- // show external triggered symbols
- if (GraphLCDSetup.ShowETSymbols && strlen(szETSymbols) > 0)
+ if (GraphLCDSetup.ShowMessages && mGraphLCDState->ShowMessage())
{
- for (i = strlen(szETSymbols) - 1; i >= 0; i--)
- {
- xPos -= symbols->Width(szETSymbols[i]) + SYMBOL_SPACE;
- bitmap->DrawCharacter(xPos, yPos, bitmap->Width() - 1, szETSymbols[i], symbols);
- }
+ display = mSkin->GetDisplay("message");
+ if (display)
+ display->Render(mScreen);
}
- }
- }
- }
-}
+#ifdef GRAPHLCD_CBITMAP_ARGB
+ mLcd->SetScreen(mScreen->Data(), mScreen->Width(), mScreen->Height());
+#else
+ mLcd->SetScreen(mScreen->Data(), mScreen->Width(), mScreen->Height(), mScreen->LineSize());
+#endif
+ mLcd->Refresh(false);
+ mLastTimeMs = currTimeMs;
+ SetBrightness();
-void cGraphLCDDisplay::DisplayProgramme()
-{
- struct tm tm_r;
- char buffer[25];
- std::string str;
- bool showTimeBar = false;
- int timeBarWidth = 0;
- int timeBarValue = 0;
- tEventState event;
-
- event = GraphLCDState->GetEventState();
- if (GraphLCDSetup.ShowProgram)
- {
- strftime(buffer, sizeof(buffer), "%R", localtime_r(&event.presentTime, &tm_r));
- if (event.followingTime && event.followingTime != event.presentTime)
- {
- str = Convert(buffer);
- if ((bitmap->Width() >= MINY_L || !IsSymbolsActive()))
- {
- str += " - ";
+ // flush events
+ mSkin->Config().GetDriver()->GetEvent();
}
else
{
- str += "-";
+#if 0
+ GLCD::cGLCDEvent * ev = mSkin->Config().GetDriver()->GetEvent();
+ if (ev && display && ((uint32_t)(currTimeMs-lastEventMs) > (uint32_t)(MIN_EVENT_DELAY) )) {
+ std::string rv = "";
+
+ if ( (rv = display->CheckAction(ev) ) != "") {
+ if (rv.substr(0,4) == "Key.") {
+ cRemote::Put(cKey::FromString(rv.substr(4).c_str()), true);
+ }
+ lastEventMs = currTimeMs;
+ }
+ }
+#endif
+ cCondWait::SleepMs(100);
}
- strftime(buffer, sizeof(buffer), "%R", localtime_r(&event.followingTime, &tm_r));
- str += buffer;
- showTimeBar = true;
- timeBarWidth = normalFont->Width(str) - 1;
- timeBarValue = (time(NULL) - event.presentTime) * timeBarWidth / (event.followingTime - event.presentTime);
- if (timeBarValue > timeBarWidth)
- timeBarValue = timeBarWidth;
- if (timeBarValue < 0)
- timeBarValue = 0;
}
else
{
- str = Convert(buffer);
- }
-
- if (!event.presentTime)
- {
- std::vector<cScroller>::iterator it;
- for (it = scroller.begin(); it != scroller.end(); it++)
- {
- it->Reset();
- }
- }
-
- if (event.presentTime)
- {
- if (scroller.size() < 1 ||
- event.presentTitle != scroller[0].Text() ||
- (scroller.size() > 1 && event.presentSubtitle != scroller[1].Text()))
- {
- if (bitmap->Height() <= MAXY_S)
- {
- scroller.resize(1);
-
- int nTopY = bitmap->Height() - (TEXT_OFFSET_Y_TITLE - 1) - largeFont->TotalHeight();
- int nMaxX = std::max(1, bitmap->Width() - 1 - (2 * FRAME_SPACE_X));
- // Logo enabled & available, and text with Logo is overlapped
- if (IsLogoActive() && nTopY < (int) logo->Height())
- {
- nMaxX -= FRAME_SPACE_XB;
- nMaxX -= logo->Width();
- nMaxX = std::max(nMaxX-2,1);//Frame around Logo
- }
- // If symbols used, and text with symbols is overlapped
- if (IsSymbolsActive())
- {
- nMaxX -= FRAME_SPACE_XB;
- nMaxX -= symbols->TotalWidth();
- nMaxX = std::max(nMaxX,1);
- }
-
- scroller[0].Init(FRAME_SPACE_X + TEXT_OFFSET_X,
- nTopY,
- nMaxX,
- largeFont, Convert(event.presentTitle.c_str()));
- }
- else
- {
- scroller.resize(2);
-
- scroller[0].Init(FRAME_SPACE_X + TEXT_OFFSET_X,
- bitmap->Height() - 2 * (TEXT_OFFSET_Y_TITLE - 1) - largeFont->TotalHeight() - normalFont->TotalHeight(),
- bitmap->Width() - 1,
- largeFont, Convert(event.presentTitle.c_str()));
- scroller[1].Init(FRAME_SPACE_X + TEXT_OFFSET_X,
- bitmap->Height() - (TEXT_OFFSET_Y_TITLE-1) - normalFont->TotalHeight(),
- bitmap->Width() - 1,
- normalFont, Convert(event.presentSubtitle.c_str()));
- }
- }
- if (bitmap->Height() <= MAXY_S)
- {
- // tiny and small LCDs
- bitmap->DrawText(FRAME_SPACE_X,
- bitmap->Height() - 2 * (TEXT_OFFSET_Y_TITLE - 1) - largeFont->TotalHeight() - normalFont->TotalHeight(),
- bitmap->Width() - 1,
- Convert(str.c_str()), normalFont);
- }
- else
- {
- // medium and large LCDs
- bitmap->DrawText(FRAME_SPACE_X,
- bitmap->Height() - 3 * (TEXT_OFFSET_Y_TITLE - 1) - largeFont->TotalHeight() - 2 * normalFont->TotalHeight() - (showTimeBar && GraphLCDSetup.ShowTimebar ? TIMEBAR_HEIGHT + 1 : 0),
- bitmap->Width() - 1,
- Convert(str.c_str()), normalFont);
- if (showTimeBar && GraphLCDSetup.ShowTimebar)
- {
- bitmap->DrawRectangle(FRAME_SPACE_X,
- bitmap->Height() - 3 * (TEXT_OFFSET_Y_TITLE - 1) - largeFont->TotalHeight() - normalFont->TotalHeight() - TIMEBAR_HEIGHT - 1,
- FRAME_SPACE_X + timeBarWidth,
- bitmap->Height() - 3 * (TEXT_OFFSET_Y_TITLE - 1) - largeFont->TotalHeight() - normalFont->TotalHeight() - 2,
- GLCD::clrBlack, false);
- bitmap->DrawRectangle(FRAME_SPACE_X,
- bitmap->Height() - 3 * (TEXT_OFFSET_Y_TITLE - 1) - largeFont->TotalHeight() - normalFont->TotalHeight() - TIMEBAR_HEIGHT - 1,
- FRAME_SPACE_X + timeBarValue,
- bitmap->Height() - 3 * (TEXT_OFFSET_Y_TITLE - 1) - largeFont->TotalHeight() - normalFont->TotalHeight() - 2,
- GLCD::clrBlack, true);
- }
- }
- // Draw Programmtext
- {
- std::vector<cScroller>::iterator it;
- for (it = scroller.begin(); it != scroller.end(); it++)
- {
- it->Draw(bitmap);
- }
- }
+ cCondWait::SleepMs(100);
}
}
+ // clear screen before thread is stopping
+ mLcd->Clear();
+ mLcd->Refresh(true);
}
-#if VDRVERSNUM >= 10701
-bool cGraphLCDDisplay::IndexIsGreaterAsOneHour(int Index, double framesPerSecond) const
-{
- return (((Index / framesPerSecond) / 3600) > 0);
-}
-#else
-bool cGraphLCDDisplay::IndexIsGreaterAsOneHour(int Index) const
-{
- int h = (Index / FRAMESPERSEC) / 3600;
- return h > 0;
-}
-#endif
-
-#if VDRVERSNUM >= 10701
-const char * cGraphLCDDisplay::IndexToMS(int Index, double framesPerSecond) const
-{
- static char buffer[16];
- int s = (Index / framesPerSecond);
-#else
-const char * cGraphLCDDisplay::IndexToMS(int Index) const
-{
- static char buffer[16];
- int s = (Index / FRAMESPERSEC);
-#endif
- int m = s / 60;
- s %= 60;
- snprintf(buffer, sizeof(buffer), "%02d:%02d", m, s);
- return buffer;
-}
-
-bool cGraphLCDDisplay::IsScrollerTextChanged(const std::vector<cScroller> & scrollers, const std::vector <std::string> & lines) const
+void cGraphLCDDisplay::Update()
{
- if (lines.size() == 0)
- return true; //Different size found
- if (scrollers.size() == 0)
- return true; //Different size found
-
- std::vector<cScroller>::const_iterator i = scrollers.begin();
- std::vector<cScroller>::const_iterator e = scrollers.end();
- std::vector<std::string>::const_iterator li = lines.begin();
- std::vector<std::string>::const_iterator le = lines.end();
-
- for (; e != i && le != li; ++li,++i)
- {
- if (i->Text() != (*li))
- return true; //Different text found
- }
- return false; //Text seem equal
+ mUpdate = true;
}
-void cGraphLCDDisplay::DisplayReplay(tReplayState & replay)
+void cGraphLCDDisplay::UpdateIn(uint64_t msec)
{
- int nMaxX, nProgressbarHeight, nTopY;
- int nWidthPreMsg = 0, nWidthCurrent = 0, nWidthTotal = 0,nWidthOffset = 0;
- std::string szPreMsg,szCurrent,szTotal;
-
- if (bitmap->Height() >= MINY_L)
- nProgressbarHeight = 15;
- else if (bitmap->Height() >= MINY_M)
- nProgressbarHeight = 9;
- else if (bitmap->Height() >= MINY_S)
- nProgressbarHeight = 5;
- else
- nProgressbarHeight = 3;
-
- if (IsLogoActive())
- nTopY = FRAME_SPACE_Y + logo->Height() + 2;
- else if (GraphLCDSetup.ShowDateTime)
- nTopY = FRAME_SPACE_Y + normalFont->TotalAscent() + 2 * TEXT_OFFSET_Y_TIME + FRAME_SPACE_YB;
- else
- nTopY = FRAME_SPACE_Y;
- if (replay.name.length() > 0)
- {
- int lineHeight, maxLines;
- std::vector <std::string> lines;
- std::string szReplayName = Convert(replay.name.c_str());
-
- nMaxX = std::max(1, bitmap->Width() - (2 * FRAME_SPACE_X) - 2 * TEXT_OFFSET_X);
- lineHeight = FRAME_SPACE_Y + largeFont->TotalHeight();
- maxLines = std::max(0, (bitmap->Height() - normalFont->TotalHeight() - FRAME_SPACE_Y - nProgressbarHeight - 2 - nTopY) / lineHeight);
-
- if (maxLines == 0)
- {
- if (IsLogoActive())
- {
- // draw replayname next to logo
- nMaxX = std::max((unsigned int) 1, nMaxX - FRAME_SPACE_X - logo->Width() - 2);
- if (GraphLCDSetup.ShowDateTime)
- nTopY = FRAME_SPACE_Y + normalFont->TotalAscent() + 2 * TEXT_OFFSET_Y_TIME + FRAME_SPACE_YB;
- else
- nTopY = FRAME_SPACE_Y;
- maxLines = (bitmap->Height() - normalFont->TotalHeight() - FRAME_SPACE_Y - nProgressbarHeight - 2 - nTopY) / lineHeight;
- }
- if (maxLines <= 1)
- {
- // use singleline mode
- lines.push_back(szReplayName);
- }
- else
- largeFont->WrapText(nMaxX, maxLines * lineHeight, szReplayName, lines);
- }
- else if (maxLines == 1) //singleline mode
- lines.push_back(szReplayName);
- else
- {
- largeFont->WrapText(nMaxX, maxLines * lineHeight, szReplayName, lines);
- }
-
- if (scroller.size() != lines.size() ||
- IsScrollerTextChanged(scroller,lines)) // if any text is changed
- {
- // Same size for Scroller and Textbuffer
- scroller.resize(lines.size());
-
- std::vector<cScroller>::iterator i = scroller.begin();
- std::vector<cScroller>::const_iterator e = scroller.end();
- std::vector<std::string>::const_iterator li = lines.begin();
- std::vector<std::string>::const_iterator le = lines.end();
-
- for (int n = lines.size(); e != i && le != li; ++li,++i,--n)
- {
- nTopY = bitmap->Height() - normalFont->TotalHeight() - FRAME_SPACE_Y - nProgressbarHeight - n * lineHeight - 2;
- i->Init(FRAME_SPACE_X + TEXT_OFFSET_X, nTopY, nMaxX + FRAME_SPACE_X + TEXT_OFFSET_X, largeFont, *li);
- }
- }
- }
-
- // Draw Replaytext
- {
- std::vector<cScroller>::iterator it;
- for (it = scroller.begin(); it != scroller.end(); it++)
- {
- it->Draw(bitmap);
- }
- }
-
- // Draw Progressbar with current and total replay time
- nTopY = bitmap->Height() - normalFont->TotalHeight() - FRAME_SPACE_Y - nProgressbarHeight - 2;
- nMaxX = std::max(1, bitmap->Width() - 1 - 2 * FRAME_SPACE_X);
- // Logo enabled & available, and text with Logo is overlapped
- if (IsLogoActive() && nTopY < (int) logo->Height())
- {
- nMaxX -= max(1,FRAME_SPACE_X); // Free line between Logo and progressbar
- nMaxX -= logo->Width();
- nMaxX = std::max(nMaxX - 2, 1); //Frame around Logo
- }
-
- bitmap->DrawRectangle(FRAME_SPACE_X,
- nTopY,
- FRAME_SPACE_X + nMaxX,
- nTopY + nProgressbarHeight,
- GLCD::clrBlack, false);
-
- DisplaySA(); //span
-
- if (1 < replay.total && 1 < replay.current) // Don't show full progressbar for endless streams
- {
- bitmap->DrawRectangle(FRAME_SPACE_X,
- nTopY,
- FRAME_SPACE_X + (std::min(replay.total, replay.current) * nMaxX / replay.total),
- nTopY + nProgressbarHeight,
- GLCD::clrBlack, true);
- }
-
- // Draw Strings with current and total replay time
- nTopY = bitmap->Height() - normalFont->TotalHeight() - FRAME_SPACE_Y;
- // use same width like Progressbar
-// if (!IsLogoActive() || nTopY > logo->Height())
-// nMaxX = max(1, bitmap->Width() - 1 - (2 * FRAME_SPACE_X));
-
- switch (replay.mode)
+ if (msec == 0)
{
- case eReplayDVD:
- szPreMsg = tr("DVD"); break;
- case eReplayMusic:
- szPreMsg = tr("Music"); break;
- case eReplayFile:
- szPreMsg = tr("File"); break;
- case eReplayImage:
- szPreMsg = tr("Image"); break;
- case eReplayAudioCD:
- szPreMsg = tr("CD"); break;
- default:
- szPreMsg = tr("Replay"); break;
- }
-
- if (bitmap->Width() >= MINY_M)
- {
- szPreMsg += " : ";
- szPreMsg += replay.loopmode;
+ mUpdateAt = 0;
}
else
- szPreMsg += ":";
-
- if (replay.mode == eReplayImage) // Image-Plugin hasn't Frames per Seconds
{
- char buffer[8];
- snprintf(buffer, sizeof(buffer), "%d", replay.current);
- szCurrent = buffer;
- snprintf(buffer, sizeof(buffer), "%d", replay.total);
- szTotal = buffer;
- }
- else
- {
-#if VDRVERSNUM >= 10701
- if ((replay.total > 1 && IndexIsGreaterAsOneHour(replay.total, replay.framesPerSecond)) ||
- IndexIsGreaterAsOneHour(replay.current, replay.framesPerSecond)) // Check if any index bigger as one hour
- {
- szCurrent = (const char *) IndexToHMSF(replay.current, false, replay.framesPerSecond);
- if (replay.total > 1) // Don't draw totaltime for endless streams
- szTotal = (const char *) IndexToHMSF(replay.total, false, replay.framesPerSecond);
- }
- else
- {
- // Show only minutes and seconds on short replays
- szCurrent = (const char *) IndexToMS(replay.current, replay.framesPerSecond);
- if (replay.total > 1) // Don't draw totaltime for endless streams
- szTotal = (const char *) IndexToMS(replay.total, replay.framesPerSecond);
- }
-#else
- if ((replay.total > 1 && IndexIsGreaterAsOneHour(replay.total)) ||
- IndexIsGreaterAsOneHour(replay.current)) // Check if any index bigger as one hour
- {
- szCurrent = (const char *) IndexToHMSF(replay.current);
- if (replay.total > 1) // Don't draw totaltime for endless streams
- szTotal = (const char *) IndexToHMSF(replay.total);
- }
- else
- {
- // Show only minutes and seconds on short replays
- szCurrent = (const char *) IndexToMS(replay.current);
- if (replay.total > 1) // Don't draw totaltime for endless streams
- szTotal = (const char *) IndexToMS(replay.total);
- }
-#endif
- }
- // Get width of drawable strings
- nWidthPreMsg = normalFont->Width(szPreMsg);
- nWidthCurrent = normalFont->Width(szCurrent);
- if (szTotal.length()) // Don't draw empty string
- nWidthTotal = normalFont->Width(szTotal);
-
- // Draw depends on display width, any placeable informations
- if (nWidthTotal && nWidthPreMsg && (nWidthPreMsg + nWidthCurrent + nWidthTotal + 5 < nMaxX))
- {
- // Show prefix and all position
- nWidthOffset = bitmap->DrawText(FRAME_SPACE_X, nTopY, nMaxX, szPreMsg, normalFont);
- bitmap->DrawText(FRAME_SPACE_X + nWidthOffset + 1, nTopY, nMaxX, szCurrent, normalFont);
- bitmap->DrawText(nMaxX - nWidthTotal, nTopY, nMaxX, szTotal, normalFont);
- }
- else if (nWidthTotal && (nWidthCurrent + nWidthTotal + 5 < nMaxX))
- {
- // Show current and total position
- bitmap->DrawText(FRAME_SPACE_X, nTopY, nMaxX, szCurrent, normalFont);
- bitmap->DrawText(nMaxX - nWidthTotal, nTopY, nMaxX, szTotal, normalFont);
- }
- else if (!nWidthTotal && nWidthPreMsg && (nWidthPreMsg + nWidthCurrent + 1 < nMaxX))
- {
- // Show prefix and current position
- nWidthOffset = bitmap->DrawText(FRAME_SPACE_X, nTopY, nMaxX, szPreMsg, normalFont);
- bitmap->DrawText(FRAME_SPACE_X + nWidthOffset + 1, nTopY, nMaxX, szCurrent, normalFont);
- }
- else
- {
- // Show only current position
- bitmap->DrawText(FRAME_SPACE_X, nTopY, nMaxX, szCurrent, normalFont);
+ mUpdateAt = cTimeMs::Now() + msec;
}
}
-void cGraphLCDDisplay::DisplayMenu(void)
+void cGraphLCDDisplay::Replaying(bool Starting)
{
- const char * pszTmp1;
- char * pszTmp2;
- int iAT, t;
- int FrameWidth, yPos, iEntryHeight;
- int extra = 0;
- tOsdState osd;
-
- osd = GraphLCDState->GetOsdState();
-
- mutex.Lock();
-
- FrameWidth = std::max(bitmap->Width() - 2 * FRAME_SPACE_X, 1);
-
- if (GraphLCDSetup.ShowDateTime == 1 ||
- (GraphLCDSetup.ShowDateTime == 2 && State != Menu))
- {
- yPos = FRAME_SPACE_Y + normalFont->TotalAscent() + 2 * TEXT_OFFSET_Y_TIME + FRAME_SPACE_YB;
- }
- else
- {
- yPos = FRAME_SPACE_Y;
- }
-
- // draw Menu Title
- if (osd.title.length() > 0)
- {
- pszTmp1 = Convert(osd.title.c_str());
- bitmap->DrawRoundRectangle(FRAME_SPACE_X,
- yPos,
- FRAME_SPACE_X + FrameWidth - 1,
- yPos + normalFont->TotalHeight() + 2 * TEXT_OFFSET_Y_TIME - 1,
- GLCD::clrBlack, true, TEXT_OFFSET_Y_CHANNEL >= 4 ? 4 : 1);
- bitmap->DrawText(FRAME_SPACE_X + TEXT_OFFSET_X,
- yPos + TEXT_OFFSET_Y_TIME,
- FRAME_SPACE_X + FrameWidth - 1,
- pszTmp1, normalFont, GLCD::clrWhite);
- }
-
- if (!(textItemLines.size() > 0))
+ if (Starting)
{
- // draw Menu Entries
- if (normalFont->TotalHeight() <= normalFont->LineHeight())
- extra = 1;
- iEntryHeight = normalFont->TotalHeight() + 2 * extra;
- yPos = yPos + normalFont->TotalHeight() + 2 * TEXT_OFFSET_Y_TIME + FRAME_SPACE_YB;
- if (GraphLCDSetup.ShowColorButtons &&
- (osd.colorButton[0].length() > 0 || osd.colorButton[1].length() > 0 ||
- osd.colorButton[2].length() > 0 || osd.colorButton[3].length() > 0))
+ if (mState != StateMenu)
{
- menuCount = (bitmap->Height() - yPos - smallFont->TotalHeight() - 4 - FRAME_SPACE_Y / 3) / iEntryHeight;
+ mState = StateReplay;
}
else
{
- menuCount = (bitmap->Height() - yPos) / iEntryHeight;
- }
-
- if (osd.currentItemIndex < menuTop)
- menuTop = osd.currentItemIndex;
- if (osd.currentItemIndex > menuTop + menuCount - 1)
- menuTop = std::max(0, osd.currentItemIndex + 1 - menuCount);
-
- bitmap->DrawRectangle(0, yPos, bitmap->Width() - 1, bitmap->Height() - 1, GLCD::clrWhite, true);
-
- for (int i = menuTop; i < std::min((int) osd.items.size(), menuTop + menuCount); i++)
- {
- if (i == osd.currentItemIndex)
- {
- bitmap->DrawRoundRectangle(FRAME_SPACE_X, yPos + (i - menuTop) * iEntryHeight,
- bitmap->Width() - 1 - FRAME_SPACE_X,
- yPos + (i - menuTop + 1) * iEntryHeight - 1,
- GLCD::clrBlack, true, TEXT_OFFSET_Y_CHANNEL >= 4 ? 3 : 1);
- }
- pszTmp1 = Convert(osd.items[i].c_str());
- pszTmp2 = (char*) strchr(pszTmp1, '\t');
- iAT = 0; t = 0;
-
- while (pszTmp1 && pszTmp2)
- {
- *pszTmp2 = '\0';
- bitmap->DrawText(FRAME_SPACE_X + TEXT_OFFSET_X + t,
- yPos + (i - menuTop) * iEntryHeight + extra,
- std::min(FRAME_SPACE_X + TEXT_OFFSET_X + t + tab[iAT + 1], bitmap->Width() - 1 - FRAME_SPACE_X),
- pszTmp1, normalFont, (i == osd.currentItemIndex) ? GLCD::clrWhite : GLCD::clrBlack);
- pszTmp1 = pszTmp2+1;
- pszTmp2 = (char*) strchr(pszTmp1, '\t');
- t = t + tab[iAT + 1] + TEXT_OFFSET_X;
- iAT++;
- }
-
- bitmap->DrawText(FRAME_SPACE_X + TEXT_OFFSET_X + t,
- yPos + (i - menuTop) * iEntryHeight + extra,
- bitmap->Width() - 1 - FRAME_SPACE_X,
- pszTmp1, normalFont, (i == osd.currentItemIndex) ? GLCD::clrWhite : GLCD::clrBlack);
- }
- }
- mutex.Unlock();
-}
-
-void cGraphLCDDisplay::DisplayMessage()
-{
- std::vector <std::string> lines;
- int lineCount;
- int maxTextLen, recW, recH;
- int entryHeight;
- tOsdState osd;
- const char * pszTmp1;
-
- osd = GraphLCDState->GetOsdState();
- if (GraphLCDSetup.ShowMessages && osd.message.length() > 0)
- {
- maxTextLen = bitmap->Width() - 2 * FRAME_SPACE_X - 2 * FRAME_SPACE_XB - 2 * TEXT_OFFSET_X - 10;
- entryHeight = 2 * (normalFont->TotalHeight() - normalFont->TotalAscent()) + normalFont->TotalAscent();
- normalFont->WrapText(maxTextLen, MAXLINES_MSG * entryHeight, osd.message, lines, &recW);
- lineCount = lines.size();
-
- // display text
- recH = lineCount * entryHeight + 2 * TEXT_OFFSET_Y_CHANNEL + 2 * FRAME_SPACE_YB;
- recW = recW + 2 * TEXT_OFFSET_X + 2 * FRAME_SPACE_XB + 2 * FRAME_SPACE_X;
- recW += (recW % 2);
-
- bitmap->DrawRectangle((bitmap->Width() - recW) / 2,
- (bitmap->Height() - recH) / 2,
- bitmap->Width() - 1 - (bitmap->Width() - recW) / 2,
- bitmap->Height() - 1 - (bitmap->Height() - recH) / 2,
- GLCD::clrWhite, true);
- recH = recH - 2 * FRAME_SPACE_YB;
- recW = recW - 2 * FRAME_SPACE_XB;
- bitmap->DrawRectangle((bitmap->Width() - recW) / 2,
- (bitmap->Height() - recH) / 2,
- bitmap->Width() - 1 - (bitmap->Width() - recW) / 2,
- bitmap->Height() - 1 - (bitmap->Height() - recH) / 2,
- GLCD::clrBlack, false);
- recH = recH - 2 * TEXT_OFFSET_Y_CHANNEL;
- recW = recW - 2 * TEXT_OFFSET_X;
- for (int i = 0; i < lineCount; i++)
- {
- pszTmp1 = Convert(lines[i].c_str());
- bitmap->DrawText((bitmap->Width() - normalFont->Width(lines[i])) / 2,
- (bitmap->Height() - recH) / 2 + i * entryHeight + (normalFont->TotalHeight() - normalFont->TotalAscent()),
- bitmap->Width() - (bitmap->Width() - recW) / 2,
- pszTmp1, normalFont);
+ mLastState = StateReplay;
}
}
-}
-
-void cGraphLCDDisplay::DisplayTextItem()
-{
- int lineCount;
- int iEntryHeight, iLineAnz;
- int yPos;
- tOsdState osd;
- const char * pszTmp1;
-
- osd = GraphLCDState->GetOsdState();
-
- mutex.Lock();
- if (textItemLines.size() > 0)
+ else
{
- lineCount = textItemLines.size();
-
- if (GraphLCDSetup.ShowDateTime == 1 ||
- (GraphLCDSetup.ShowDateTime == 2 && State != Menu))
+ if (mState != StateMenu)
{
- yPos = FRAME_SPACE_Y + normalFont->TotalAscent() + 2 * TEXT_OFFSET_Y_TIME + FRAME_SPACE_YB;
+ mState = StateNormal;
}
else
{
- yPos = FRAME_SPACE_Y;
- }
-
- // draw Text
- iEntryHeight = normalFont->LineHeight();
- yPos = yPos + normalFont->TotalAscent() + 2 * TEXT_OFFSET_Y_CHANNEL + FRAME_SPACE_YB;
- if (GraphLCDSetup.ShowColorButtons &&
- (osd.colorButton[0].length() > 0 || osd.colorButton[1].length() > 0 ||
- osd.colorButton[2].length() > 0 || osd.colorButton[3].length() > 0))
- {
- iLineAnz = (bitmap->Height() - yPos - smallFont->TotalHeight() - 4 - FRAME_SPACE_Y / 3) / iEntryHeight;
- }
- else
- {
- iLineAnz = (bitmap->Height() - yPos) / iEntryHeight;
- }
-
- int startLine = textItemTop;
- for (int i = 0; i < std::min(lineCount, iLineAnz); i++)
- {
- if (i + startLine < lineCount) {
- pszTmp1 = Convert(textItemLines[i + startLine].c_str());
- bitmap->DrawText(FRAME_SPACE_X + TEXT_OFFSET_X,
- yPos + i * iEntryHeight,
- bitmap->Width() - 1 - FRAME_SPACE_X,
- pszTmp1, normalFont);
- }
+ mLastState = StateNormal;
}
}
- mutex.Unlock();
+ Update();
}
-void cGraphLCDDisplay::DisplayColorButtons()
+void cGraphLCDDisplay::SetMenuClear()
{
- int i, buttonWidth, textLen;
- int extra = 0;
- tOsdState osd;
- const char * pszTmp1;
-
- osd = GraphLCDState->GetOsdState();
+ if (mSkin)
+ mSkin->SetTSEvalSwitch(cTimeMs::Now());
- if (GraphLCDSetup.ShowColorButtons)
+ mSkinConfig->SetMenuClear();
+ if (mState == StateMenu)
{
- buttonWidth = (bitmap->Width() / 4) - (FRAME_SPACE_X ? 2 * FRAME_SPACE_X : 1);
- if (smallFont->TotalHeight() == smallFont->TotalAscent())
- extra = 1;
-
- for (i = 0; i < 4; i++)
- {
- if (osd.colorButton[i].length() > 0)
- {
- pszTmp1 = Convert(osd.colorButton[i].c_str());
- bitmap->DrawRoundRectangle(i * (bitmap->Width() / 4) + FRAME_SPACE_X,
- bitmap->Height() - smallFont->TotalHeight() - 2 * extra - FRAME_SPACE_Y / 3,
- i * (bitmap->Width() / 4) + FRAME_SPACE_X + buttonWidth - 1,
- bitmap->Height() - 1 - FRAME_SPACE_Y / 3,
- GLCD::clrBlack, true, std::max(1, (smallFont->TotalHeight() + 4) / 5));
- textLen = smallFont->Width(osd.colorButton[i]);
- if (textLen <= buttonWidth - 2)
- {
- bitmap->DrawText(i * (bitmap->Width() / 4) + (bitmap->Width() / 8) - (textLen + 1) / 2,
- bitmap->Height() - smallFont->TotalHeight() - extra - FRAME_SPACE_Y / 3,
- i * (bitmap->Width() / 4) + FRAME_SPACE_X + buttonWidth - 1,
- pszTmp1, smallFont, GLCD::clrWhite);
- }
- else
- {
- bitmap->DrawText(i * (bitmap->Width() / 4) + FRAME_SPACE_X + 1,
- bitmap->Height() - smallFont->TotalHeight() - extra - FRAME_SPACE_Y / 3,
- i * (bitmap->Width() / 4) + FRAME_SPACE_X + buttonWidth - 1,
- pszTmp1, smallFont, GLCD::clrWhite);
- }
- }
- }
+ mState = mLastState;
+ // activate delayed Update
+ UpdateIn(100);
}
-}
-
-void cGraphLCDDisplay::DisplayVolume()
-{
- int RecW, RecH;
- tVolumeState volume;
-
- volume = GraphLCDState->GetVolumeState();
-
- if (GraphLCDSetup.ShowVolume)
+ else
{
- if (volume.lastChange > 0)
- {
- if (TimeMs() - volume.lastChange < 2000)
- {
- RecH = (bitmap->Height() / 5) + 2 * FRAME_SPACE_YB + 4 * FRAME_SPACE_YB;
- RecW = bitmap->Width() / 2;
- bitmap->DrawRoundRectangle((bitmap->Width() - RecW) / 2, // draw frame
- (bitmap->Height() - RecH) / 2,
- bitmap->Width() - (bitmap->Width() - RecW) / 2 - 1,
- bitmap->Height() - (bitmap->Height() - RecH) / 2 - 1,
- GLCD::clrWhite, true, 1);
- RecH = RecH - 2 * FRAME_SPACE_YB;
- RecW = RecW - 2 * FRAME_SPACE_XB;
- bitmap->DrawRoundRectangle((bitmap->Width() - RecW) / 2, // draw box
- (bitmap->Height() - RecH) / 2,
- bitmap->Width() - 1 - (bitmap->Width() - RecW) / 2,
- bitmap->Height() - 1 - (bitmap->Height() - RecH) / 2,
- GLCD::clrBlack, false, 1);
- RecH = RecH - 2;
- RecW = RecW - 2;
- if (volume.value > 0)
- bitmap->DrawRectangle((bitmap->Width() - RecW) / 2, // draw bar
- (bitmap->Height() - RecH) / 2,
- (bitmap->Width() - RecW) / 2 + (volume.value * RecW) / 255,
- bitmap->Height() - 1 - (bitmap->Height() - RecH) / 2,
- GLCD::clrBlack, true);
- if (volume.value == 0)
- {
- // display big mute symbol
- bitmap->DrawCharacter(bitmap->Width() / 2 - symbols->Width('5'),
- bitmap->Height() / 2 - symbols->Height('5'),
- bitmap->Width() - 1, '5', symbols);
- bitmap->DrawCharacter(bitmap->Width() / 2,
- bitmap->Height() / 2 - symbols->Height('6'),
- bitmap->Width() - 1, '6', symbols);
- bitmap->DrawCharacter(bitmap->Width() / 2 - symbols->Width('7'),
- bitmap->Height() / 2,
- bitmap->Width() - 1, '7', symbols);
- bitmap->DrawCharacter(bitmap->Width() / 2,
- bitmap->Height() / 2,
- bitmap->Width() - 1, '8', symbols);
- }
- showVolume = true;
- }
- }
+ Update();
}
}
-void cGraphLCDDisplay::UpdateIn(long usec)
+void cGraphLCDDisplay::SetMenuTitle()
{
- if (usec == 0)
+ if (mState != StateMenu)
{
- timerclear(&UpdateAt);
- }
- else
- {
- if (gettimeofday(&CurrTimeval, NULL) == 0)
- {
- // get current time
- UpdateAt.tv_sec = CurrTimeval.tv_sec;
- UpdateAt.tv_usec = CurrTimeval.tv_usec + usec;
- while (UpdateAt.tv_usec >= 1000000)
- {
- // take care of an overflow
- UpdateAt.tv_sec++;
- UpdateAt.tv_usec -= 1000000;
- }
- }
+ mLastState = mState;
+ mState = StateMenu;
}
+ UpdateIn(100);
}
-
-bool cGraphLCDDisplay::CheckAndUpdateSymbols()
+void cGraphLCDDisplay::SetMenuCurrent()
{
- bool bRet = false;
- static struct stat filestat;
- FILE* InFile = NULL;
- static char szLine[8];
-
- if (stat(FILENAME_EXTERNAL_TRIGGERED_SYMBOLS, &filestat)==0) {
- if (LastTimeModSym != filestat.st_mtime) {
- InFile = fopen(FILENAME_EXTERNAL_TRIGGERED_SYMBOLS, "r");
- if (InFile) {
- strcpy(szETSymbols, "");
- while (!feof(InFile) && (strlen(szETSymbols)+1<sizeof(szLine))) {
- strcpy(szLine, "");
- fgets(szLine, sizeof(szLine), InFile);
- compactspace(szLine);
- if ((strlen(szLine)==2) && (szLine[1]=='1')) {
- strcat(szETSymbols, ".");
- szETSymbols[strlen(szETSymbols)-1] = szLine[0];
- }
- }
- fclose(InFile);
- LastTimeModSym = filestat.st_mtime;
- bRet = true;
- }
- }
- } else {
- if ((errno == ENOENT) && (strlen(szETSymbols)>0)) {
- strcpy(szETSymbols, "");
- bRet = true;
- }
+ if (mState != StateMenu)
+ {
+ mLastState = mState;
+ mState = StateMenu;
}
- return bRet;
+ UpdateIn(100);
}
void cGraphLCDDisplay::SetBrightness()
{
- mutex.Lock();
+ //mutex.Lock();
bool bActive = bBrightnessActive
- || (State == Menu)
- || (GraphLCDSetup.ShowVolume && showVolume)
- || (GraphLCDSetup.ShowMessages && GraphLCDState->GetOsdState().message.length() > 0)
+ || (mState == StateMenu)
+ || (GraphLCDSetup.ShowVolume && mShowVolume)
+ || (GraphLCDSetup.ShowMenu && mShowAudio)
+ || (GraphLCDSetup.ShowMessages && mGraphLCDState->ShowMessage())
|| (GraphLCDSetup.BrightnessDelay == 900);
if (bActive)
{
- LastTimeBrightness = TimeMs();
+ LastTimeBrightness = cTimeMs::Now();
bBrightnessActive = false;
}
if ((bActive ? GraphLCDSetup.BrightnessActive : GraphLCDSetup.BrightnessIdle) != nCurrentBrightness)
@@ -2026,211 +514,28 @@ void cGraphLCDDisplay::SetBrightness()
else
{
if (GraphLCDSetup.BrightnessDelay < 1
- || ((TimeMs() - LastTimeBrightness) > (uint64_t) (GraphLCDSetup.BrightnessDelay*1000)))
+ || ((unsigned int)(cTimeMs::Now() - LastTimeBrightness) > (unsigned int)(GraphLCDSetup.BrightnessDelay*1000)))
{
mLcd->SetBrightness(GraphLCDSetup.BrightnessIdle);
nCurrentBrightness = GraphLCDSetup.BrightnessIdle;
}
}
}
- mutex.Unlock();
-}
-
-#ifdef USE_WAREAGLEICON
-const char * cGraphLCDDisplay::ConvertWarEagleIconsUtf8(const char *s)
-{
- if (textWithIcons)
- free(textWithIcons);
- textWithIcons = (char *)malloc(sizeof(char *) * strlen(s) + 10);
- textWithIcons[0] = '\0';
- int sl;
- uint sym;
- char * iconChar;
- iconChar = (char *)malloc(sizeof(char *) * 4);
- iconChar[0] = '\0';
- // will replace unicode access codes with non-unicode ones between
- // start and end code of wareagle icons defined in VDRSymbols.ttf,
- // see http://andreas.vdr-developer.org/fonts/symbols.html and iconpatch.h of
- // vdr sources patched with USE_WAREAGLEICON support:
- uint symStart = 0xE000; // ICON_RESUME_UTF8
- //uint symEnd = 0xE000 + 0x15; // ICON_CLOCK_LH_UTF8
- uint symEnd = 0xE000 + 0x1C; // last custom icon beyond ICON_CLOCK_LH_UTF8
- int symOffset = - 0xDF80;
- for (const char *p = s; *p; )
- {
- sl = Utf8CharLen(p);
- sym = Utf8CharGet(p, sl);
- if (sym >= symStart && sym <= symEnd)
- {
- sl = Utf8CharSet(sym + symOffset, iconChar);
- strncat(textWithIcons, iconChar, sl - 1);
- }
- else
- {
- strncat(textWithIcons, p, sl);
- }
- p += sl;
- }
- free (iconChar);
- return textWithIcons;
+ //mutex.Unlock();
}
-#endif
-const char * cGraphLCDDisplay::Convert(const char *s)
-{
-// do character recoding to ISO-8859-1
-// code based on jowi24s vdr-lcdprog
- if (!s || !*s) {
- return s;
- }
- const char *s_converted = conv->Convert(s);
- if (s_converted == s) {
- const char* SCT = cCharSetConv::SystemCharacterTable() ? cCharSetConv::SystemCharacterTable() : "UTF-8";
- esyslog("graphlcd plugin: ERROR: conversion from %s to UTF-8 failed.", SCT);
- esyslog("graphlcd plugin: ERROR: '%s'",s);
- }
-#ifdef USE_WAREAGLEICON
- if (bIsUTF8)
- return ConvertWarEagleIconsUtf8(s_converted);
- else
-#endif
- return s_converted;
+void cGraphLCDDisplay::ForceUpdateBrightness() {
+ bBrightnessActive = true;
+ SetBrightness();
}
-
-void cGraphLCDDisplay::DisplaySA() //span
-{
-// Spectrum Analyzer visualization
- if ( GraphLCDSetup.enableSpectrumAnalyzer && GraphLCDSetup.pluginSpectrumAnalyzer )
- {
- if (cPluginManager::CallFirstService(SPAN_GET_BAR_HEIGHTS_ID, NULL))
- {
- Span_GetBarHeights_v1_0 GetBarHeights;
-
- int bandsSA = 20;
- int falloffSA = 8;
- int channelsSA = 1;
-
- unsigned int bar;
- unsigned int *barHeights = new unsigned int[bandsSA];
- unsigned int *barHeightsLeftChannel = new unsigned int[bandsSA];
- unsigned int *barHeightsRightChannel = new unsigned int[bandsSA];
- unsigned int volumeLeftChannel;
- unsigned int volumeRightChannel;
- unsigned int volumeBothChannels;
- unsigned int *barPeaksBothChannels = new unsigned int[bandsSA];
- unsigned int *barPeaksLeftChannel = new unsigned int[bandsSA];
- unsigned int *barPeaksRightChannel = new unsigned int[bandsSA];
-
- GetBarHeights.bands = bandsSA;
- GetBarHeights.barHeights = barHeights;
- GetBarHeights.barHeightsLeftChannel = barHeightsLeftChannel;
- GetBarHeights.barHeightsRightChannel = barHeightsRightChannel;
- GetBarHeights.volumeLeftChannel = &volumeLeftChannel;
- GetBarHeights.volumeRightChannel = &volumeRightChannel;
- GetBarHeights.volumeBothChannels = &volumeBothChannels;
- GetBarHeights.name = "graphlcd";
- GetBarHeights.falloff = falloffSA;
- GetBarHeights.barPeaksBothChannels = barPeaksBothChannels;
- GetBarHeights.barPeaksLeftChannel = barPeaksLeftChannel;
- GetBarHeights.barPeaksRightChannel = barPeaksRightChannel;
-
- if ( cPluginManager::CallFirstService(SPAN_GET_BAR_HEIGHTS_ID, &GetBarHeights ))
- {
- int i;
- int barWidth = 2;
- int saStartX = FRAME_SPACE_X;
- int saEndX = saStartX + barWidth*bandsSA*2 + bandsSA/4 - 1;
- int saStartY = FRAME_SPACE_Y;
- int saEndY = FRAME_SPACE_Y + bitmap->Height()/2 - 3;
-
- LastTimeSA.Set(100);
-
- if ( GraphLCDSetup.SAShowVolume )
- {
-
- saStartX = FRAME_SPACE_X + bitmap->Width()/2 - (barWidth*bandsSA*2 + bandsSA/4)/2 - 2;
- saEndX = saStartX + barWidth*bandsSA*2 + bandsSA/4 - 1;
-
- // left volume
- bitmap->DrawRectangle(FRAME_SPACE_X,
- saStartY,
- saStartX-1,
- saEndY + 1,
- GLCD::clrWhite, true);
-
- for ( i=0; (i<(int)logo->Width()/2-2) && (i<3*((int)volumeLeftChannel*(int)saStartX)/100); i++)
- {
- bitmap->DrawRectangle(saStartX - i - 2,
- saStartY + saEndY/2 - i,
- saStartX - i - 4,
- saStartY + saEndY/2 + i,
- GLCD::clrBlack, true);
- }
-
- // right volume
- bitmap->DrawRectangle(saEndX + 1,
- saStartY,
- bitmap->Width() - 1,
- saEndY + 1,
- GLCD::clrWhite, true);
-
- for ( i=0; (i<(int)logo->Width()/2-2) && (i<3*((int)volumeRightChannel*(int)saStartX)/100); i++)
- {
- bitmap->DrawRectangle(saEndX + 2 + i,
- saStartY + saEndY/2 - i,
- saEndX + i + 4,
- saStartY + saEndY/2 + i,
- GLCD::clrBlack, true);
- }
- }
- // black background
- bitmap->DrawRectangle(saStartX,
- saStartY,
- saEndX,
- saEndY + 1,
- GLCD::clrBlack, true);
-
- for ( i=0; i < bandsSA; i++ )
- {
-/*
- if ( channelsSA == 2 )
- {
- bar = barHeightsLeftChannel[i];
- bar = barHeightsRightChannel[i];
- }
-*/
- if ( channelsSA == 1)
- {
- // the bar
- bar = (barHeights[i]*(saEndY-saStartY))/100;
- bitmap->DrawRectangle(saStartX + barWidth*2*(i)+ barWidth + 1,
- saEndY,
- saStartX + barWidth*2*(i) + barWidth+ barWidth + 1,
- saEndY - bar,
- GLCD::clrWhite, true);
-
- // the peak
- bar = (barPeaksBothChannels[i]*(saEndY-saStartY))/100;
- if ( bar > 0 )
- {
- bitmap->DrawRectangle(saStartX + barWidth*2*(i)+ barWidth + 1,
- saEndY - bar,
- saStartX + barWidth*2*(i) + barWidth+ barWidth + 1,
- saEndY - bar+1,
- GLCD::clrWhite, true);
- }
- }
- }
- }
-
- delete [] barHeights;
- delete [] barHeightsLeftChannel;
- delete [] barHeightsRightChannel;
- delete [] barPeaksBothChannels;
- delete [] barPeaksLeftChannel;
- delete [] barPeaksRightChannel;
- }
- }
+void cGraphLCDDisplay::Clear() {
+ mScreen->Clear();
+#ifdef GRAPHLCD_CBITMAP_ARGB
+ mLcd->SetScreen(mScreen->Data(), mScreen->Width(), mScreen->Height());
+#else
+ mLcd->SetScreen(mScreen->Data(), mScreen->Width(), mScreen->Height(), mScreen->LineSize());
+#endif
+ mLcd->Refresh(false);
}