From 8c63e0fd967a7ac037872ca5af378dc92f0410fa Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sun, 27 Nov 2005 18:00:00 +0100 Subject: =?UTF-8?q?Version=201.3.37=20-=20Added=20compiler=20options=20"-f?= =?UTF-8?q?PIC=20-g"=20to=20all=20plugins=20(thanks=20to=20Rolf=20Ahrenber?= =?UTF-8?q?g).=20-=20Fixed=20initializing=20the=20day=20index=20when=20edi?= =?UTF-8?q?ting=20the=20weekday=20parameter=20of=20a=20=20=20repeating=20t?= =?UTF-8?q?imer=20(thanks=20to=20Marco=20Schl=C3=BC=C3=9Fler).=20-=20No=20?= =?UTF-8?q?longer=20removing=20superfluous=20hyphens=20in=20EPG=20data=20-?= =?UTF-8?q?=20would=20become=20too=20=20=20language=20dependent=20to=20han?= =?UTF-8?q?dle=20all=20kinds=20of=20exceptions.=20-=20Modified=20switching?= =?UTF-8?q?=20to=20Dolby=20Digital=20audio=20in=20live=20mode,=20if=20the?= =?UTF-8?q?=20driver=20=20=20and=20firmware=20can=20handle=20live=20DD=20w?= =?UTF-8?q?ithout=20the=20need=20of=20a=20Transfer=20Mode=20(thanks=20=20?= =?UTF-8?q?=20to=20Werner=20Fink).=20Live=20DD=20mode=20requires=20a=20ful?= =?UTF-8?q?l=20featured=20DVB=20card=20and=20a=20=20=20LinuxDVB=20driver?= =?UTF-8?q?=20with=20firmware=20version=200x2622=20or=20higher.=20Older=20?= =?UTF-8?q?versions=20will=20=20=20use=20Transfer=20Mode=20just=20like=20b?= =?UTF-8?q?efore.=20-=20Implemented=20handling=20of=20the=20"CA=20PMT=20Re?= =?UTF-8?q?ply"=20for=20CAMs=20(thanks=20to=20Marco=20=20=20Schl=C3=BC?= =?UTF-8?q?=C3=9Fler=20for=20figuring=20out=20some=20obscure=20length=20by?= =?UTF-8?q?tes=20in=20the=20CA=20PMT=20Reply=20=20=20data=20of=20AlphaCryp?= =?UTF-8?q?t=20CAMs).=20-=20Some=20preparations=20for=20being=20able=20to?= =?UTF-8?q?=20record=20several=20encrypted=20channels=20from=20=20=20the?= =?UTF-8?q?=20same=20transponder=20at=20the=20same=20time=20(or=20record?= =?UTF-8?q?=20and=20view=20different=20encrypted=20=20=20channels),=20prov?= =?UTF-8?q?ided=20the=20CAM=20in=20use=20can=20handle=20this.=20This=20is?= =?UTF-8?q?=20work=20in=20progress=20=20=20and=20isn't=20actively=20used,?= =?UTF-8?q?=20yet.=20-=20Fixed=20SetProgress()=20in=20the=20'skincurses'?= =?UTF-8?q?=20plugin=20in=20case=20Total=20is=200=20(reported=20=20=20by?= =?UTF-8?q?=20Stefan=20Huelswitt).=20-=20Added=20a=20copy=20constructor=20?= =?UTF-8?q?to=20cString=20and=20fixed=20its=20assignment=20operator=20=20?= =?UTF-8?q?=20(thanks=20to=20Holger=20Brunn).=20-=20The=20new=20function?= =?UTF-8?q?=20Skins.QueueMessage()=20can=20be=20called=20from=20a=20backgr?= =?UTF-8?q?ound=20thread=20=20=20to=20queue=20a=20message=20for=20display.?= =?UTF-8?q?=20See=20VDR/skins.h=20for=20details.=20-=20The=20SVDRP=20comma?= =?UTF-8?q?nd=20MESG=20uses=20the=20new=20message=20queueing=20facility,?= =?UTF-8?q?=20so=20MESG=20=20=20commands=20may=20now=20be=20executed=20at?= =?UTF-8?q?=20any=20time,=20and=20the=20message=20will=20be=20displayed=20?= =?UTF-8?q?=20=20(no=20more=20"pending=20message").?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- skins.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 127 insertions(+), 2 deletions(-) (limited to 'skins.c') diff --git a/skins.c b/skins.c index e81e882..c6213cf 100644 --- a/skins.c +++ b/skins.c @@ -4,13 +4,49 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: skins.c 1.5 2005/10/02 10:12:10 kls Exp $ + * $Id: skins.c 1.6 2005/11/27 15:52:25 kls Exp $ */ #include "skins.h" #include "interface.h" #include "status.h" -#include "tools.h" + +// --- cSkinQueuedMessage ---------------------------------------------------- + +class cSkinQueuedMessage : public cListObject { + friend class cSkins; +private: + eMessageType type; + char *message; + int seconds; + int timeout; + tThreadId threadId; + eKeys key; + int state; + cMutex mutex; + cCondVar condVar; +public: + cSkinQueuedMessage(eMessageType Type, const char *s, int Seconds, int Timeout); + virtual ~cSkinQueuedMessage(); + }; + +cSkinQueuedMessage::cSkinQueuedMessage(eMessageType Type, const char *s, int Seconds, int Timeout) +{ + type = Type; + message = s ? strdup(s) : NULL; + seconds = Seconds; + timeout = Timeout; + threadId = cThread::ThreadId(); + key = kNone; + state = 0; // waiting +} + +cSkinQueuedMessage::~cSkinQueuedMessage() +{ + free(message); +} + +cList SkinQueuedMessages; // --- cSkinDisplay ---------------------------------------------------------- @@ -202,6 +238,95 @@ eKeys cSkins::Message(eMessageType Type, const char *s, int Seconds) return k; } +int cSkins::QueueMessage(eMessageType Type, const char *s, int Seconds, int Timeout) +{ + if (Type == mtStatus) { + dsyslog("cSkins::QueueMessage() called with mtStatus - ignored!"); + return kNone; + } + if (isempty(s)) { + dsyslog("cSkins::QueueMessage() called with empty message - ignored!"); + return kNone; + } + int k = kNone; + if (Timeout > 0) { + if (cThread::IsMainThread()) { + dsyslog("cSkins::QueueMessage() called from main thread with Timeout = %d - ignored!", Timeout); + return k; + } + cSkinQueuedMessage *m = new cSkinQueuedMessage(Type, s, Seconds, Timeout); + queueMessageMutex.Lock(); + SkinQueuedMessages.Add(m); + m->mutex.Lock(); + queueMessageMutex.Unlock(); + if (m->condVar.TimedWait(m->mutex, Timeout * 1000)) + k = m->key; + else + k = -1; // timeout, nothing has been displayed + m->state = 2; // done + m->mutex.Unlock(); + } + else { + queueMessageMutex.Lock(); + // Check if there is a waiting message w/o timeout for this thread: + if (Timeout == -1) { + for (cSkinQueuedMessage *m = SkinQueuedMessages.Last(); m; m = SkinQueuedMessages.Prev(m)) { + if (m->threadId == cThread::ThreadId()) { + if (m->state == 0 && m->timeout == -1) + m->state = 2; // done + break; + } + } + } + // Add the new message: + SkinQueuedMessages.Add(new cSkinQueuedMessage(Type, s, Seconds, Timeout)); + queueMessageMutex.Unlock(); + } + return k; +} + +void cSkins::ProcessQueuedMessages(void) +{ + if (!cThread::IsMainThread()) { + dsyslog("cSkins::ProcessQueuedMessages() called from background thread - ignored!"); + return; + } + cSkinQueuedMessage *msg = NULL; + // Get the first waiting message: + queueMessageMutex.Lock(); + for (cSkinQueuedMessage *m = SkinQueuedMessages.First(); m; m = SkinQueuedMessages.Next(m)) { + if (m->state == 0) { // waiting + m->state = 1; // active + msg = m; + break; + } + } + queueMessageMutex.Unlock(); + // Display the message: + if (msg) { + msg->mutex.Lock(); + if (msg->state == 1) { // might have changed since we got it + msg->key = Skins.Message(msg->type, msg->message, msg->seconds); + if (msg->timeout == 0) + msg->state = 2; // done + else + msg->condVar.Broadcast(); + } + msg->mutex.Unlock(); + } + // Remove done messages from the queue: + queueMessageMutex.Lock(); + for (;;) { + cSkinQueuedMessage *m = SkinQueuedMessages.First(); + if (m && m->state == 2) { // done + SkinQueuedMessages.Del(m); + } + else + break; + } + queueMessageMutex.Unlock(); +} + void cSkins::Flush(void) { if (cSkinDisplay::Current()) -- cgit v1.2.3