From 3dcf1a4b91239cbf2cd4386639503083469a9689 Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Thu, 22 Nov 2007 23:44:42 +0000 Subject: [PATCH] *** empty log message *** --- command.cc | 8 ++ timers.h | 46 ++++++++ vdrresponsepacket.cc | 6 ++ vdrresponsepacket.h | 2 + vepg.cc | 6 +- vvideolivetv.cc | 244 +++++++++++++++++++++++++++++++++---------- vvideolivetv.h | 14 ++- 7 files changed, 267 insertions(+), 59 deletions(-) diff --git a/command.cc b/command.cc index 528a937..8edb347 100644 --- a/command.cc +++ b/command.cc @@ -426,6 +426,14 @@ void Command::processMessage(Message* m) } else { + /* FIXME + + Instead of sending through the boxstack, implement a more generic MessageReceiver interface + and have potential receivers register with something + When a message needs to be delivered, check if the receiver is still registered, if so, deliver the message + This could all be done using the existing big command mutex to keep it simple + */ + logger->log("Command", Log::DEBUG, "Sending message to boxstack"); boxstack->processMessage(m); } diff --git a/timers.h b/timers.h index 55ddc9a..bdebc40 100755 --- a/timers.h +++ b/timers.h @@ -1,3 +1,49 @@ + + + + + + + + + +/* + + +FYI + +Timers ... deprecated. Maybe. + +This whole thing will be replaced with a timed-message idea. It will be possible +to send yourself (or whoever) a message with a delay, or delivery time. The message +will be handed to Command as usual, but command will do the right thing. The messages +will be delivered to the recipient _with the gui mutex locked_, meaning updates can +be done there and then in the message handler. + +Good points: +* Cuts down on code lines +* Most (all?) timercall()s eventually send a message to command in order to + do something within The Big Mutex. This makes it easier and simpler code wise +* Gets rid of Timers. +* Hopefully gets rid of most postMessageFromOuterSpace calls + +Bad points: +* Timers become gui only features. Solve this with a MessageReceiver interface and + have command deliver messages straight to the recipients rather than through BoxStack. +* Timer delivery accuracy becomes dependant on everything that uses The Big Mutex. + It will become more important to not block The Big Mutex. +* Cancelling timers... hmm + +If you have any comments about the new design, like, "It's just as flawed as the old one", +then I'd appreciate hearing it before I start writing it all :) + + +*/ + + + + + /* Copyright 2004-2005 Chris Tallon diff --git a/vdrresponsepacket.cc b/vdrresponsepacket.cc index 3f3810e..e9ca08b 100644 --- a/vdrresponsepacket.cc +++ b/vdrresponsepacket.cc @@ -21,6 +21,7 @@ #include "vdrresponsepacket.h" #include "vdr.h" +#include "tcp.h" VDR_ResponsePacket::VDR_ResponsePacket() { @@ -63,6 +64,11 @@ bool VDR_ResponsePacket::end() return (packetPos >= userDataLength); } +void VDR_ResponsePacket::dumpUD() +{ + TCP::dump(userData, userDataLength); +} + int VDR_ResponsePacket::serverError() { if ((packetPos == 0) && (userDataLength == 4) && !ntohl(*(ULONG*)userData)) return 1; diff --git a/vdrresponsepacket.h b/vdrresponsepacket.h index e37edd6..dc35869 100644 --- a/vdrresponsepacket.h +++ b/vdrresponsepacket.h @@ -52,6 +52,8 @@ class VDR_ResponsePacket bool end(); + void dumpUD(); + // Do this a better way? UCHAR* getBlock_getUserData(); diff --git a/vepg.cc b/vepg.cc index 4982be3..a12cf85 100644 --- a/vepg.cc +++ b/vepg.cc @@ -428,7 +428,7 @@ int VEpg::handleCommand(int command) if (!chanList) return 2; // select programme and display menu TODO currently just changes to selected channel - videoLive->channelChange(VVideoLive::NUMBER, (*chanList)[chanListbox.getCurrentOption()]->number); + if (videoLive) videoLive->channelChange(VVideoLive::NUMBER, (*chanList)[chanListbox.getCurrentOption()]->number); if(command == Remote::GO) return 2; @@ -450,12 +450,12 @@ int VEpg::handleCommand(int command) } case Remote::CHANNELUP: { - videoLive->channelChange(VVideoLive::OFFSET, VVideoLive::UP); + if (videoLive) videoLive->channelChange(VVideoLive::OFFSET, VVideoLive::UP); return 2; } case Remote::CHANNELDOWN: { - videoLive->channelChange(VVideoLive::OFFSET, VVideoLive::DOWN); + if (videoLive) videoLive->channelChange(VVideoLive::OFFSET, VVideoLive::DOWN); return 2; } } diff --git a/vvideolivetv.cc b/vvideolivetv.cc index e9a387d..a698eb6 100644 --- a/vvideolivetv.cc +++ b/vvideolivetv.cc @@ -34,6 +34,8 @@ #include "vaudioselector.h" #include "colour.h" #include "event.h" +#include "timers.h" +#include "vepg.h" VVideoLiveTV::VVideoLiveTV(ChannelList* tchanList, ULONG initialChannelNumber, VChannelList* tvchannelList) { @@ -50,6 +52,8 @@ VVideoLiveTV::VVideoLiveTV(ChannelList* tchanList, ULONG initialChannelNumber, V osdChannelIndex = 0; keying = 0; + playing = false; + // Convert channel number to index UINT i; for(i = 0; i < chanList->size(); i++) @@ -105,7 +109,6 @@ VVideoLiveTV::VVideoLiveTV(ChannelList* tchanList, ULONG initialChannelNumber, V clock.setBackgroundColour(Colour::BLACK); clock.setPosition(osd.getWidth() - 100, 4); clock.setSize(90, 30); - clock.setText("00:00"); osd.add(&clock); osdChanNum.setBackgroundColour(Colour::BLACK); @@ -170,6 +173,8 @@ VVideoLiveTV::VVideoLiveTV(ChannelList* tchanList, ULONG initialChannelNumber, V VVideoLiveTV::~VVideoLiveTV() { + if (playing) stop(); + // delete player; video->setDefaultAspect(); } @@ -178,8 +183,16 @@ int VVideoLiveTV::handleCommand(int command) { switch(command) { - case Remote::STOP: case Remote::BACK: + { + if (osd.getVisible()) + { + removeOSD(); + return 2; + } + // else drop through to stop + } + case Remote::STOP: case Remote::MENU: { stop(); @@ -190,18 +203,14 @@ int VVideoLiveTV::handleCommand(int command) { // New remote only // epg data up - sl.up(); - sl.draw(); - boxstack->update(this, osd.getRegion()); + doUp(); return 2; } case Remote::DOWN: { // New remote only // epg data down - sl.down(); - sl.draw(); - boxstack->update(this, osd.getRegion()); + doDown(); return 2; } case Remote::LEFT: @@ -240,7 +249,6 @@ int VVideoLiveTV::handleCommand(int command) doOK(); return 2; } - case Remote::GUIDE: case Remote::RED: { return 2; @@ -279,14 +287,16 @@ int VVideoLiveTV::handleCommand(int command) BoxStack::getInstance()->update(vas); */ } -#ifdef DEV case Remote::YELLOW: { + return 2; } + case Remote::GUIDE: case Remote::BLUE: { + doEPG(); + return 2; } -#endif } return 1; @@ -294,17 +304,21 @@ int VVideoLiveTV::handleCommand(int command) void VVideoLiveTV::go() { - doNowNext(); - osd.setVisible(true); + playing = true; draw(); boxstack->update(this); - // set a timer for osd deletion + setClock(); + displayOSD(); + // start player } void VVideoLiveTV::stop() -{ +{ + Timers::getInstance()->cancelTimer(this, 1); + Timers::getInstance()->cancelTimer(this, 2); + playing = false; } void VVideoLiveTV::doNowNext() @@ -372,87 +386,106 @@ void VVideoLiveTV::doOK() { if (osd.getVisible()) { - if (osdChannelIndex == currentChannelIndex) + if (keying) { - osd.setVisible(false); - draw(); - boxstack->update(this, osd.getRegion()); + UINT newChannel = 0; + for(int i = keying - 1; i >= 0; i--) newChannel += keyingInput[i] * (ULONG)pow(10, i); + + channelChange(NUMBER, newChannel); + osdChannelIndex = currentChannelIndex; + displayOSD(); + } + else if (osdChannelIndex == currentChannelIndex) + { + removeOSD(); } else { channelChange(INDEX, osdChannelIndex); - doNowNext(); - draw(); - boxstack->update(this, osd.getRegion()); + displayOSD(); } } else { osdChannelIndex = currentChannelIndex; - doNowNext(); - osd.setVisible(true); - draw(); - boxstack->update(this, osd.getRegion()); - // set a timer for deletion of osd + displayOSD(); } } void VVideoLiveTV::doLeft() { if (osd.getVisible()) - { osdChannelIndex = downChannel(osdChannelIndex); - } else - { osdChannelIndex = currentChannelIndex; - osd.setVisible(true); - } - doNowNext(); - draw(); - boxstack->update(this, osd.getRegion()); + displayOSD(); } void VVideoLiveTV::doRight() { if (osd.getVisible()) - { osdChannelIndex = upChannel(osdChannelIndex); + else + osdChannelIndex = currentChannelIndex; + + displayOSD(); +} + +void VVideoLiveTV::doUp() +{ + if (osd.getVisible()) + { + sl.up(); + sl.draw(); + boxstack->update(this, osd.getRegion()); + Timers::getInstance()->setTimerD(this, 1, 8); // arrows pressed, go to 8s timer } else { - osdChannelIndex = currentChannelIndex; - osd.setVisible(true); - } + displayOSD(); + } +} - doNowNext(); - draw(); - boxstack->update(this, osd.getRegion()); +void VVideoLiveTV::doDown() +{ + if (osd.getVisible()) + { + sl.down(); + sl.draw(); + boxstack->update(this, osd.getRegion()); + Timers::getInstance()->setTimerD(this, 1, 8); // arrows pressed, go to 8s timer + } + else + { + displayOSD(); + } } void VVideoLiveTV::doChanUp() { channelChange(OFFSET, UP); osdChannelIndex = currentChannelIndex; - doNowNext(); - draw(); - boxstack->update(this, osd.getRegion()); + + displayOSD(); } void VVideoLiveTV::doChanDown() { channelChange(OFFSET, DOWN); osdChannelIndex = currentChannelIndex; - doNowNext(); - draw(); - boxstack->update(this, osd.getRegion()); + + displayOSD(); } void VVideoLiveTV::doKey(int command) { + if (!osd.getVisible()) // First key. prep the data + { + doNowNext(); + } + int i; - for (i = keying - 1; i >= 0; i--) keyingInput[i+1] = keyingInput[i]; keyingInput[0] = command; keying++; @@ -470,15 +503,116 @@ void VVideoLiveTV::doKey(int command) channelChange(NUMBER, newChannel); osdChannelIndex = currentChannelIndex; - doNowNext(); - draw(); - boxstack->update(this, osd.getRegion()); + displayOSD(); } else { - osdChanNum.setText(keyingString); - osdChanNum.draw(); + // Special, modified displayOSD + if (!osd.getVisible()) + { + osd.setVisible(true); + osdChanNum.setText(keyingString); + draw(); + } + else + { + osdChanNum.setText(keyingString); + osdChanNum.draw(); + } boxstack->update(this, osd.getRegion()); + Timers::getInstance()->setTimerD(this, 1, 3); // 3s for keying input + } +} + +void VVideoLiveTV::displayOSD() +{ + osd.setVisible(true); + doNowNext(); + draw(); + boxstack->update(this, osd.getRegion()); + Timers::getInstance()->setTimerD(this, 1, 4); +} + +void VVideoLiveTV::removeOSD() +{ + Timers::getInstance()->cancelTimer(this, 1); + osd.setVisible(false); + draw(); + boxstack->update(this, osd.getRegion()); +} + +void VVideoLiveTV::setClock() +{ + char timeString[20]; + time_t t; + time(&t); + struct tm* tms = localtime(&t); + strftime(timeString, 19, "%H:%M", tms); + clock.setText(timeString); + + 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()->setTimerT(this, 2, dt); +} + +void VVideoLiveTV::doEPG() +{ + if (osd.getVisible()) removeOSD(); + + video->setMode(Video::QUARTER); + video->setPosition(170, 5); //TODO need to deal with 4:3 switching + + VEpg* vepg = new VEpg(NULL, currentChannelIndex, VDR::VIDEO); + vepg->draw(); + boxstack->add(vepg); + boxstack->update(vepg); +} + +void VVideoLiveTV::timercall(int ref) +{ + if (ref == 1) + { + if (keying) + { + // Really, now that cancelTimer basically protects us from deletion, why can't we execute gui stuff here? + + UINT newChannel = 0; + for(int i = keying - 1; i >= 0; i--) newChannel += keyingInput[i] * (ULONG)pow(10, i); + + Message* m = new Message(); + m->message = Message::CHANNEL_CHANGE; + m->to = this; + m->parameter = newChannel; + Command::getInstance()->postMessageFromOuterSpace(m); // FIXME cjt yeah you know what. + } + else + { + osd.setVisible(false); + draw(); + Message* m = new Message(); + m->message = Message::REDRAW; + m->to = BoxStack::getInstance(); + m->from = this; + m->parameter = (ULONG)osd.getRegion(); + Command::getInstance()->postMessageFromOuterSpace(m); // FIXME cjt yeah you know what. + } + } + else if (ref == 2) + { + setClock(); + if (osd.getVisible()) + { + clock.draw(); + Message* m = new Message(); + m->message = Message::REDRAW; + m->to = BoxStack::getInstance(); + m->from = this; + m->parameter = (ULONG)osd.getRegion(); + Command::getInstance()->postMessageFromOuterSpace(m); // FIXME cjt yeah you know what. + } } } @@ -542,6 +676,8 @@ void VVideoLiveTV::processMessage(Message* m) else if (m->message == Message::CHANNEL_CHANGE) { channelChange(NUMBER, m->parameter); + osdChannelIndex = currentChannelIndex; + displayOSD(); } else if (m->message == Message::EPG_CLOSE) { diff --git a/vvideolivetv.h b/vvideolivetv.h index 26a2a79..23799bd 100644 --- a/vvideolivetv.h +++ b/vvideolivetv.h @@ -31,8 +31,8 @@ #include "vdr.h" #include "wtextbox.h" #include "wselectlist.h" +#include "timerreceiver.h" -class VEpg; class VChannelList; class Video; class VChannelList; @@ -40,7 +40,7 @@ class BoxStack; class WTextbox; //class PlayerLiveTV; -class VVideoLiveTV : public Boxx +class VVideoLiveTV : public Boxx, public TimerReceiver { public: VVideoLiveTV(ChannelList* chanList, ULONG initialChannelNumber, VChannelList* vchannelList); @@ -62,11 +62,14 @@ class VVideoLiveTV : public Boxx const static UCHAR UP = 1; const static UCHAR DOWN = 2; + void timercall(int ref); + private: BoxStack* boxstack; VDR* vdr; Video* video; // PlayerLiveTV* player; + bool playing; ChannelList* chanList; VChannelList* vchannelList; EventList* eventList; @@ -88,9 +91,15 @@ class VVideoLiveTV : public Boxx void doOK(); void doLeft(); void doRight(); + void doUp(); + void doDown(); void doChanUp(); void doChanDown(); void doKey(int command); + void displayOSD(); + void removeOSD(); + void setClock(); + void doEPG(); Wwss wss; Region wssRegion; @@ -109,6 +118,7 @@ class VVideoLiveTV : public Boxx WTextbox textGreen; WTextbox textYellow; WTextbox textBlue; + }; #endif -- 2.39.5