Move EPG to the right a bit, timers fixes and improvements
authorChris Tallon <chris@vomp.tv>
Sun, 4 Dec 2005 19:44:07 +0000 (19:44 +0000)
committerChris Tallon <chris@vomp.tv>
Sun, 4 Dec 2005 19:44:07 +0000 (19:44 +0000)
16 files changed:
colour.cc
command.cc
message.h
timers.cc
timers.h
vepg.cc
viewman.cc
vlivebanner.cc
vlivebanner.h
vmute.cc
vmute.h
vvideolive.cc
vvideolive.h
vvolume.cc
vvolume.h
vwelcome.cc

index cf1d38a7dac639e0ac9a6a5568665c59da282b2c..06c9992220fe8511ea1f1ac0e078883f1ed41325 100644 (file)
--- a/colour.cc
+++ b/colour.cc
@@ -25,6 +25,7 @@ Real colours
 */
 Colour Colour::BLACK(0, 0, 0);
 Colour Colour::RED(255, 0, 0);
+Colour Colour::GREEN(0, 255, 0);
 Colour Colour::VIDEOBLUE(0, 0, 150);
 Colour Colour::VIEWBACKGROUND(0, 0, 100);
 Colour Colour::TITLEBARBACKGROUND(0, 0, 200);
index 60c9f8ced8f2601925bf42a4dc88a4deaba447dd..16f98ec5e37b3eb32dbc4f6eed74646248f71571 100644 (file)
@@ -215,6 +215,10 @@ void Command::processMessage(Message* m)
       // objects deriving from messagequeues, make them derive from
       // messagereceiver - then one messagequeue can deliver any message to anywhere
 
+      // Try to segfault
+      logger->log("Command", Log::DEBUG, "1: %p", m);
+      logger->log("Command", Log::DEBUG, "2: %p", m->to);
+      logger->log("Command", Log::DEBUG, "3: %lu", m->parameter);
 
       // deliver timer
 
index 873b4bc77cb405d3bb0ff47e3c62f48836f788b7..b238ec4ce8baf6a401656d7c632f2b3ff596c673 100644 (file)
--- a/message.h
+++ b/message.h
@@ -55,6 +55,7 @@ class Message
     const static ULONG CHILD_CLOSE = 17;
     const static ULONG REDRAW_LANG = 18;
     const static ULONG TIMER = 19;
+    const static ULONG EPG = 20;
 };
 
 #endif
index d1ac5e85b6a1216c4b6c9ef6a3151b5e1b23ce78..280cc73f2d772b3591cc1d42208adc57e39893dd 100755 (executable)
--- a/timers.cc
+++ b/timers.cc
@@ -48,7 +48,7 @@ int Timers::init()
   logger->log("Timers", Log::DEBUG, "Timers init start");\r
 \r
   threadLock(); // lock here, the thread loop will unlock and wait\r
-logger->log("Timers", Log::DEBUG, "LOCKED -TIMERS- MUTEX 1");\r
+  //logger->log("Timers", Log::DEBUG, "LOCKED -TIMERS- MUTEX 1");\r
   if (!threadStart())\r
   {\r
     shutdown();\r
@@ -84,66 +84,71 @@ int Timers::shutdown()
   return 1;\r
 }\r
 \r
-int Timers::setTimer(TimerReceiver* client, int clientReference, time_t requestedTime)\r
+int Timers::setTimer(TimerReceiver* client, int clientReference, long int requestedTime, long int requestedTimeNSEC)\r
 {\r
   if (!initted) return 0;\r
 \r
   logger->log("Timers", Log::DEBUG, "Starting set timer 1");\r
 \r
+  //logger->log("Timers", Log::DEBUG, "Waiting for LOCK -TIMERS- MUTEX 2");\r
+  threadLock();\r
+\r
+  // Check that this timer is not already in the list\r
+  TimerList::iterator i;\r
+  Timer* currentTimer = NULL;\r
+  for(i = timerList.begin(); i != timerList.end(); i++)\r
+  {\r
+    currentTimer = *i;\r
+    if ((currentTimer->client == client) && (currentTimer->clientReference == clientReference))\r
+    {\r
+      // Overwrite an existing timer\r
+      currentTimer->requestedTime.tv_sec = requestedTime;\r
+      currentTimer->requestedTime.tv_nsec = requestedTimeNSEC;\r
+      resetThreadFlag = true;\r
+      threadSignalNoLock();\r
+\r
+      //logger->log("Timers", Log::DEBUG, "about to un-LOCK -TIMERS- MUTEX 2 (b)");\r
+      threadUnlock();\r
+      return 0;\r
+    }\r
+  }\r
+\r
   Timer* t = new Timer();\r
   t->client = client;\r
   t->clientReference = clientReference;\r
   t->requestedTime.tv_sec = requestedTime;\r
-  t->requestedTime.tv_nsec = 0;\r
+  t->requestedTime.tv_nsec = requestedTimeNSEC;\r
 \r
-logger->log("Timers", Log::DEBUG, "Waiting for LOCK -TIMERS- MUTEX 2");\r
-  threadLock();\r
-logger->log("Timers", Log::DEBUG, "LOCKED -TIMERS- MUTEX 2");\r
+  //logger->log("Timers", Log::DEBUG, "LOCKED -TIMERS- MUTEX 2");\r
   timerList.push_back(t);\r
   resetThreadFlag = true;\r
   threadSignalNoLock();\r
-logger->log("Timers", Log::DEBUG, "about to un-LOCK -TIMERS- MUTEX 2");\r
+  //logger->log("Timers", Log::DEBUG, "about to un-LOCK -TIMERS- MUTEX 2");\r
   threadUnlock();\r
 \r
-  logger->log("Timers", Log::DEBUG, "1 Have set timer for %p ref %i", client, clientReference);\r
+  logger->log("Timers", Log::DEBUG, "Timer set for %p ref %i", client, clientReference);\r
 \r
   return 1;\r
 }\r
 \r
 int Timers::setTimer(TimerReceiver* client, int clientReference, struct timespec duration)\r
 {\r
-  if (!initted) return 0;\r
-\r
-  logger->log("Timers", Log::DEBUG, "Starting set timer 2");\r
-\r
-  Timer* t = new Timer();\r
-  t->client = client;\r
-  t->clientReference = clientReference;\r
-\r
   struct timespec currentTime;\r
   clock_gettime(CLOCK_REALTIME, &currentTime);\r
 \r
-  t->requestedTime.tv_sec = currentTime.tv_sec + duration.tv_sec;\r
-  t->requestedTime.tv_nsec = currentTime.tv_nsec + duration.tv_nsec;\r
-  if (t->requestedTime.tv_nsec > 999999999)\r
+  long int requestedTime;\r
+  long int requestedTimeNSEC;\r
+\r
+  requestedTime = currentTime.tv_sec + duration.tv_sec;\r
+  requestedTimeNSEC = currentTime.tv_nsec + duration.tv_nsec;\r
+  if (requestedTimeNSEC > 999999999)\r
   {\r
-    ++t->requestedTime.tv_sec;\r
-    t->requestedTime.tv_nsec -= 1000000000;\r
+    ++requestedTime;\r
+    requestedTimeNSEC -= 1000000000;\r
     logger->log("Timers", Log::DEBUG, "Second rollover - CHECK FIXME");\r
   }\r
 \r
-logger->log("Timers", Log::DEBUG, "Waiting for LOCK -TIMERS- MUTEX 3");\r
-  threadLock();\r
-logger->log("Timers", Log::DEBUG, "LOCKED -TIMERS- MUTEX 3");\r
-  timerList.push_back(t);\r
-  resetThreadFlag = true;\r
-  threadSignalNoLock();\r
-logger->log("Timers", Log::DEBUG, "about to un-LOCK -TIMERS- MUTEX 3");\r
-  threadUnlock();\r
-\r
-  logger->log("Timers", Log::DEBUG, "2 Have set timer for %p ref %i", client, clientReference);\r
-\r
-  return 1;\r
+  return setTimer(client, clientReference, requestedTime, requestedTimeNSEC);\r
 }\r
 \r
 int Timers::cancelTimer(TimerReceiver* client, int clientReference)\r
@@ -152,15 +157,15 @@ int Timers::cancelTimer(TimerReceiver* client, int clientReference)
 \r
   logger->log("Timers", Log::DEBUG, "Starting cancel timer %p %i, list size = %i", client, clientReference, timerList.size());\r
 \r
-logger->log("Timers", Log::DEBUG, "Waiting for LOCK -TIMERS- MUTEX 4");\r
+  //logger->log("Timers", Log::DEBUG, "Waiting for LOCK -TIMERS- MUTEX 4");\r
   threadLock();\r
-logger->log("Timers", Log::DEBUG, "LOCKED -TIMERS- MUTEX 4");\r
+  //logger->log("Timers", Log::DEBUG, "LOCKED -TIMERS- MUTEX 4");\r
   TimerList::iterator i;\r
   Timer* currentTimer = NULL;\r
   for(i = timerList.begin(); i != timerList.end(); i++)\r
   {\r
     currentTimer = *i;\r
-    logger->log("Timers", Log::DEBUG, "I: %p %i : %p %i", client, clientReference, currentTimer->client, currentTimer->clientReference);\r
+    //logger->log("Timers", Log::DEBUG, "I: %p %i : %p %i", client, clientReference, currentTimer->client, currentTimer->clientReference);\r
     if ((currentTimer->client == client) && (currentTimer->clientReference == clientReference))\r
     {\r
       timerList.erase(i);\r
@@ -173,14 +178,14 @@ logger->log("Timers", Log::DEBUG, "LOCKED -TIMERS- MUTEX 4");
   {\r
     // no timer found\r
     logger->log("Timers", Log::DEBUG, "No timer found in cancelTimer %p ref %i", client, clientReference);\r
-logger->log("Timers", Log::DEBUG, "about to un-LOCK -TIMERS- MUTEX 4");\r
+    //logger->log("Timers", Log::DEBUG, "about to un-LOCK -TIMERS- MUTEX 4");\r
     threadUnlock();\r
     return 0;\r
   }\r
 \r
   resetThreadFlag = true;\r
   threadSignalNoLock();\r
-logger->log("Timers", Log::DEBUG, "about to un-LOCK -TIMERS- MUTEX 4");\r
+  //logger->log("Timers", Log::DEBUG, "about to un-LOCK -TIMERS- MUTEX 4");\r
   threadUnlock();\r
 \r
 \r
@@ -241,20 +246,20 @@ void Timers::threadMethod()
 \r
     if (nextTimer)\r
     {\r
-      logger->log("Timers", Log::DEBUG, "List size: %i. nextTimer: %p. nextTime.tv_sec: %li. nextTime.tv_nsec: %li", timerList.size(), nextTimer, nextTime.tv_sec, nextTime.tv_nsec);\r
+      logger->log("Timers", Log::DEBUG, "List size: %i. nextTimerClient: %p/%i. nextTime.tv_sec: %li. nextTime.tv_nsec: %li", timerList.size(), nextTimer->client, nextTimer->clientReference, nextTime.tv_sec, nextTime.tv_nsec);\r
 \r
 \r
-logger->log("Timers", Log::DEBUG, "about to un-LOCK -TIMERS- MUTEX (1)");\r
+      //logger->log("Timers", Log::DEBUG, "about to un-LOCK -TIMERS- MUTEX (1)");\r
       threadWaitForSignalTimed(&nextTime); // FIXME does this work if the time is in the past?\r
-logger->log("Timers", Log::DEBUG, "LOCKED -TIMERS- MUTEX 5");\r
+      //logger->log("Timers", Log::DEBUG, "LOCKED -TIMERS- MUTEX 5");\r
 \r
       // unlocks in the wait\r
     }\r
     else\r
     {\r
-logger->log("Timers", Log::DEBUG, "about to un-LOCK -TIMERS- MUTEX (2)");\r
+      //logger->log("Timers", Log::DEBUG, "about to un-LOCK -TIMERS- MUTEX (2)");\r
       threadWaitForSignal();\r
-logger->log("Timers", Log::DEBUG, "LOCKED -TIMERS- MUTEX 6");\r
+      //logger->log("Timers", Log::DEBUG, "LOCKED -TIMERS- MUTEX 6");\r
       // unlocks in the wait\r
     }\r
 \r
@@ -290,12 +295,12 @@ logger->log("Timers", Log::DEBUG, "LOCKED -TIMERS- MUTEX 6");
       // now unlock the timers mutex for a fraction of a second\r
       // in case the gui thread is waiting on the timers mutex\r
       threadUnlock();\r
-logger->log("Timers", Log::DEBUG, "un-LOCKED -TIMERS- MUTEX (3)");\r
-      printf("\n\n\n WOOOOO \n\n\n The anti deadlock code is working!!! \n\n\n");\r
-      usleep(10000); // 5ms - too long?\r
-logger->log("Timers", Log::DEBUG, "Waiting for LOCK -TIMERS- MUTEX 7");\r
+      //logger->log("Timers", Log::DEBUG, "un-LOCKED -TIMERS- MUTEX (3)");\r
+      //printf("\n\n\n WOOOOO \n\n\n The anti deadlock code is working!!! \n\n\n");\r
+      usleep(10000); // 10ms - too long?\r
+      //logger->log("Timers", Log::DEBUG, "Waiting for LOCK -TIMERS- MUTEX 7");\r
       threadLock();\r
-logger->log("Timers", Log::DEBUG, "LOCKED -TIMERS- MUTEX 7");\r
+      //logger->log("Timers", Log::DEBUG, "LOCKED -TIMERS- MUTEX 7");\r
       resetThreadFlag = true;\r
     }\r
     else\r
index 3a88b069af00232e994e419b0de929689dd68c83..c9e20ecb2bf09d2d23db3a1e3488c1cae616d092 100755 (executable)
--- a/timers.h
+++ b/timers.h
 #include "command.h"\r
 #include "timerreceiver.h"\r
 \r
+// FIXME - ensure all objects that call settimer call cancel timer if they are being deleted\r
+\r
+/*\r
+\r
+Timers documentation\r
+\r
+Call setTimer to set a timer.... cancelTimer to delete a running timer.\r
+Derive your object from TimerReceiver (timerreceiver.h), implement timercall() in your class\r
+and supply your 'this' pointer to setTimer.\r
+\r
+Once a timer has fired it does not exist anymore, you have to keep creating them if you want\r
+a constant pulse.\r
+\r
+clientReference is any int of your choice. It will be supplied back to you in the timercall()\r
+so you can identify which timer has fired if you have more than one.\r
+\r
+You can reset a timer by calling setTimer again. This will not create 2 timers, it will overwrite the first one.\r
+\r
+You must not allow a timer to fire on an object that has been deleted already, unless you want\r
+segfaulty hell.\r
+\r
+*/\r
+\r
 class Timer\r
 {\r
   public:\r
@@ -53,9 +76,7 @@ class Timers : public Thread
     int init();\r
     int shutdown();\r
 \r
-    // FIXME - ensure all objects that call settimer call cancel timer if they are being deleted\r
-\r
-    int setTimer(TimerReceiver* client, int clientReference, time_t requestedTime);\r
+    int setTimer(TimerReceiver* client, int clientReference, long int requestedTime, long int requestedTimeNSEC=0);\r
     int setTimer(TimerReceiver* client, int clientReference, timespec duration);\r
     int cancelTimer(TimerReceiver* client, int clientReference);\r
 \r
diff --git a/vepg.cc b/vepg.cc
index 190a401883f38ced6fae745dae65bcffb4ffbda4..a28b53b2af629620b9eb1b261a4e619d4180e39f 100644 (file)
--- a/vepg.cc
+++ b/vepg.cc
@@ -50,7 +50,7 @@ VEpg::VEpg(VVideoLive* v, UINT currentChannel)
   if (Video::getInstance()->getFormat() == Video::PAL)\r
   {\r
     create(632, 520);\r
-    setScreenPos(44, 30);\r
+    setScreenPos(60, 30);\r
   }\r
   else\r
   {\r
index 5c106efba8641a6c30966fef833847854c8ec617..ab5ab979aa8204b94f9d1e9b59a1449aa5b5efe0 100644 (file)
@@ -130,7 +130,6 @@ void ViewMan::deleteView(int z)
   }
 }
 
-// FIXME - make this take a optional region for smaller updates (not whole views)
 void ViewMan::updateView(View* toUpdate, Region* regionToUpdate)
 {
   // Get the z index of the view
index 4af19cde8e6fce24dc3ecdec6365710bcb2413dc..9b275994f6340453d9afb4780792c00c7c84d3a5 100644 (file)
 
 #include "vlivebanner.h"
 
+VLiveBanner* VLiveBanner::instance = NULL;
+
 VLiveBanner::VLiveBanner(View* tparent, Channel* channel, bool bannerTakesCommands)
 {
+  instance = this;
   eventList = NULL;
   parent = tparent;
   takeCommands = bannerTakesCommands;
 
+  clockRegion.x = 440;
+  clockRegion.y = 0;
+  clockRegion.w = 60;
+  clockRegion.h = 30;
+
   create(500, 120);
   if (Video::getInstance()->getFormat() == Video::PAL)
   {
@@ -51,9 +59,17 @@ VLiveBanner::VLiveBanner(View* tparent, Channel* channel, bool bannerTakesComman
 
 VLiveBanner::~VLiveBanner()
 {
+  instance = NULL;
+  Timers::getInstance()->cancelTimer(this, 1);
+  Timers::getInstance()->cancelTimer(this, 2);
   delData();
 }
 
+VLiveBanner* VLiveBanner::getInstance()
+{
+  return instance;
+}
+
 void VLiveBanner::delData()
 {
   if (eventList)
@@ -111,7 +127,6 @@ void VLiveBanner::setChannel(Channel* tChannel)
     }
 
     // Reset the timer as it probably took 1-2 seconds to change the channel
-    Timers::getInstance()->cancelTimer(this, 1); // if it exists
     Timers::getInstance()->setTimer(this, 1, (struct timespec){4, 0});
   }
 }
@@ -124,6 +139,11 @@ void VLiveBanner::draw()
 
   rectangle(7, area.h - 24, 18, 16, Colour::RED);
   drawText(tr("info"), 32, area.h - 25, Colour::LIGHTTEXT);
+
+  rectangle(110, area.h - 24, 18, 16, Colour::GREEN);
+  drawText(tr("EPG"), 135, area.h - 25, Colour::LIGHTTEXT);
+
+  drawClock();
 }
 
 int VLiveBanner::handleCommand(int command)
@@ -146,6 +166,10 @@ int VLiveBanner::handleCommand(int command)
       sl.draw();
 
       show();
+
+      // Arrows pressed, go to an 8s timer
+      Timers::getInstance()->setTimer(this, 1, (struct timespec){8, 0});
+
       return 2;
     }
     case Remote::DF_DOWN:
@@ -158,6 +182,10 @@ int VLiveBanner::handleCommand(int command)
       sl.draw();
 
       show();
+
+      // Arrows pressed, go to an 8s timer
+      Timers::getInstance()->setTimer(this, 1, (struct timespec){8, 0});
+
       return 2;
     }
     case Remote::CHANNELUP:
@@ -225,6 +253,17 @@ int VLiveBanner::handleCommand(int command)
       }
       return 2; // should not get here
     }
+    case Remote::GREEN:
+    {
+      // full epg
+      Timers::getInstance()->cancelTimer(this, 1); // if it exists
+      Message* m = new Message();
+      m->message = Message::EPG;
+      m->to = parent;
+      m->from = this;
+      ViewMan::getInstance()->postMessage(m);
+      return 4;
+    }
   }
 
   return 1;
@@ -232,10 +271,39 @@ int VLiveBanner::handleCommand(int command)
 
 void VLiveBanner::timercall(int clientReference)
 {
-  // delete me!
-  Message* m = new Message();
-  m->message = Message::CLOSE_ME;
-  m->to = ViewMan::getInstance();
-  m->from = this;
-  ViewMan::getInstance()->postMessage(m);
+  if (clientReference == 1)
+  {
+    // delete me!
+    Message* m = new Message();
+    m->message = Message::CLOSE_ME;
+    m->to = ViewMan::getInstance();
+    m->from = this;
+    ViewMan::getInstance()->postMessage(m);
+  }
+  else if (clientReference == 2)
+  {
+    // redraw clock
+    drawClock();
+    ViewMan::getInstance()->updateView(this, &clockRegion);
+  }
+}
+
+void VLiveBanner::drawClock()
+{
+  // Blank the area first
+  rectangle(area.w - 60, 0, 60, 30, titleBarColour);
+
+  char timeString[20];
+  time_t t;
+  time(&t);
+  struct tm* tms = localtime(&t);
+  strftime(timeString, 19, "%H:%M", tms);
+  drawTextRJ(timeString, 490, 5, Colour::LIGHTTEXT);
+
+  time_t dt = 60 - (t % 60);  // seconds to the next minute
+  if (dt == 0) dt = 60; // advance a whole minute if necessary
+  dt += t;  // get a time_t value for it rather than using duration
+  // (so it will occur at the actual second and not second and a half)
+
+  Timers::getInstance()->setTimer(this, 2, dt);
 }
index fe3620709d8dc6d272c472e183f8d68e255ac0a5..05f2f78051e121661dbd3eef4f87b1f8183749d8 100644 (file)
@@ -44,6 +44,7 @@ class VLiveBanner : public View, public TimerReceiver
   public:
     VLiveBanner(View* parent, Channel* channel, bool bannerTakesCommands);
     ~VLiveBanner();
+    static VLiveBanner* getInstance();
     void delData();
 
     void setChannel(Channel* channel);
@@ -53,12 +54,14 @@ class VLiveBanner : public View, public TimerReceiver
     void timercall(int clientReference);
 
   private:
+    static VLiveBanner* instance;
     View* parent;
     WSelectList sl;
     Channel* currentChannel;
     EventList* eventList;
     bool takeCommands;
-
+    void drawClock();
+    Region clockRegion;
 };
 
 #endif
index c7fee0c81ea3dc7054609da2a9482c1387730e35..46d6b1f9e1c30ac2acb00866808cb3e73d74e110 100644 (file)
--- a/vmute.cc
+++ b/vmute.cc
@@ -37,6 +37,12 @@ VMute::VMute()
   setBackgroundColour(Colour::VIEWBACKGROUND);
 }
 
+VMute::~VMute()
+{
+  // Make sure the timer is deleted
+  Timers::getInstance()->cancelTimer(this, 1);
+}
+
 void VMute::draw()
 {
   View::draw();
@@ -48,7 +54,6 @@ void VMute::draw()
   w.setSurfaceOffset(5, 5);
   w.draw();
 
-  Timers::getInstance()->cancelTimer(this, 1); // if it exists
   Timers::getInstance()->setTimer(this, 1, (struct timespec){2, 0});
 }
 
diff --git a/vmute.h b/vmute.h
index 263729dc517fec349ee6284bf24647159ec2c81d..3709115feece97e00014cd8a4671ab9dffdced5f 100644 (file)
--- a/vmute.h
+++ b/vmute.h
@@ -37,6 +37,7 @@ class VMute : public View, public TimerReceiver
 {
   public:
     VMute();
+    ~VMute();
     void draw();
     int handleCommand(int command);
     void timercall(int clientReference);
index f96b5bccf07f17edf06ba7492191bf7344c26dbe..8dfd9c64364c9cd53b5c7d5565f4dbbe842aa611 100644 (file)
@@ -33,7 +33,6 @@ VVideoLive::VVideoLive(ChannelList* tchanList, ULONG tstreamType)
   unavailable = 0;
   unavailableView = NULL;
   streamType = tstreamType;
-  vlb = (VLiveBanner*)1; // Can't be NULL because then that is sent to ViewMan::remove and it takes the top view off .. FIXME!
   epgmode=false;
   if (streamType == VDR::RADIO) player = new PlayerVideo(Command::getInstance(), 0, 1);
   else                          player = new PlayerVideo(Command::getInstance(), 0, 0);
@@ -97,6 +96,13 @@ int VVideoLive::handleCommand(int command)
       channelChange(OFFSET, DOWN);
       return 2;
     }
+    case Remote::PREVCHANNEL:
+    {
+      if (unavailable) showUnavailable(0);
+      else stop();
+      channelChange(PREVIOUS, 0);
+      return 2;
+    }
     case Remote::OK:
     {
       doBanner(true);
@@ -174,6 +180,7 @@ void VVideoLive::processMessage(Message* m)
     channelChange(OFFSET, UP);
     if(!epgmode)
     {
+      VLiveBanner* vlb = VLiveBanner::getInstance(); // guaranteed to be one
       vlb->setChannel((*chanList)[currentChannel]);
       vlb->draw();
       vlb->show();
@@ -185,6 +192,7 @@ void VVideoLive::processMessage(Message* m)
     channelChange(OFFSET, DOWN);
     if(!epgmode)
     {
+      VLiveBanner* vlb = VLiveBanner::getInstance(); // guaranteed to be one
       vlb->setChannel((*chanList)[currentChannel]);
       vlb->draw();
       vlb->show();
@@ -196,13 +204,26 @@ void VVideoLive::processMessage(Message* m)
     stop();
     play(1);
   }
+  else if (m->message == Message::EPG)
+  {
+    Log::getInstance()->log("VVideoLive", Log::DEBUG, "EPG requested from live banner");
+
+    if (!epgmode)
+    {
+      showEPG();
+      epgmode=!epgmode; // shouldn't this be within the braces? // same for above in handleCommand, ask Brian FIXME
+    }
+  }
 }
 
 void VVideoLive::doBanner(bool bannerTakesCommands)
 {
   if(epgmode)
     return;
-  vlb = new VLiveBanner(this, (*chanList)[currentChannel], bannerTakesCommands);
+
+  if (VLiveBanner::getInstance()) return; // there already is one
+
+  VLiveBanner* vlb = new VLiveBanner(this, (*chanList)[currentChannel], bannerTakesCommands);
 
   Message* m = new Message();
   m->from = this;
@@ -274,7 +295,7 @@ void VVideoLive::stop(int noRemoveVLB)
 printf("1\n");
   if (unavailable) return;
 printf("2\n");
-  if (!noRemoveVLB) viewman->removeView(vlb); // if live banner is present, remove it. won't cause damage if its not present
+  if (!noRemoveVLB && VLiveBanner::getInstance()) viewman->removeView(VLiveBanner::getInstance()); // if live banner is present, remove it. won't cause damage if its not present
 printf("3\n");
 
   player->stop();
index ae6e51efdcddf8733ddd75e059ccd02350ed06b3..0f496b404961366ebab6c390c85b86cb3c644640 100644 (file)
@@ -82,7 +82,6 @@ class VVideoLive : public View
     int unavailable;
     VInfo* unavailableView;
     ULONG streamType;
-    VLiveBanner* vlb;
 
     UINT upChannel();
     UINT downChannel();
index b9de8cbcc01ed519ece030e0357644459e4d2617..c6adf7de7ebaa005b209d1402d43df9874825586 100644 (file)
@@ -37,6 +37,12 @@ VVolume::VVolume()
   setBackgroundColour(Colour::VIEWBACKGROUND);
 }
 
+VVolume::~VVolume()
+{
+  // Make sure the timer is deleted
+  Timers::getInstance()->cancelTimer(this, 1);
+}
+
 void VVolume::draw()
 {
   View::draw();
@@ -63,7 +69,6 @@ void VVolume::draw()
     w.draw();
   }
 
-  Timers::getInstance()->cancelTimer(this, 1); // if it exists
   Timers::getInstance()->setTimer(this, 1, (struct timespec){2, 0});
 }
 
index a7915b9d22310b7df06aaa850caedb990d6f043a..ce24717c581b62bcb2d80517dc82dedfa3dd6882 100644 (file)
--- a/vvolume.h
+++ b/vvolume.h
@@ -37,6 +37,7 @@ class VVolume : public View, public TimerReceiver
 {
   public:
     VVolume();
+    ~VVolume();
     void draw();
     int handleCommand(int command);
     void timercall(int clientReference);
index 7ee0c6f5d36b9743cc032f4d18e95bcbc0f0cbeb..cd2ebca6b95a2132d80aa1c8d2c33c8643cc3ca6 100644 (file)
@@ -98,9 +98,13 @@ void VWelcome::drawClock()
   struct tm* tms = localtime(&t);
   strftime(timeString, 19, "%H:%M", tms);
   drawTextRJ(timeString, 450, 5, Colour::LIGHTTEXT);
-  time_t dt = 60 - (t % 60);
-  if (dt == 0) dt = 60;
-  Timers::getInstance()->setTimer(this, 1, (struct timespec){dt, 0});
+
+  time_t dt = 60 - (t % 60);  // seconds to the next minute
+  if (dt == 0) dt = 60; // advance a whole minute if necessary
+  dt += t;  // get a time_t value for it rather than using duration
+  // (so it will occur at the actual second and not second and a half)
+
+  Timers::getInstance()->setTimer(this, 1, dt);
 }
 
 void VWelcome::timercall(int clientReference)