diff -Naur vdr-1.5.8.org/Makefile vdr-1.5.8/Makefile --- vdr-1.5.8.org/Makefile 2008-01-23 17:52:47.472777750 -0500 +++ vdr-1.5.8/Makefile 2008-01-23 18:09:08.234944394 -0500 @@ -46,6 +46,8 @@ # SUBMENU + TinyXML OBJS += tinystr.o tinyxml.o tinyxmlerror.o tinyxmlparser.o submenu.o +OBJS += osdcontroller.o + ifndef NO_KBD DEFINES += -DREMOTE_KBD endif diff -Naur vdr-1.5.8.org/osd.c vdr-1.5.8/osd.c --- vdr-1.5.8.org/osd.c 2008-01-23 17:56:06.687263222 -0500 +++ vdr-1.5.8/osd.c 2008-01-23 18:09:08.252945697 -0500 @@ -15,6 +15,7 @@ #include #include #include "tools.h" +#include "osdcontroller.h" // --- cPalette -------------------------------------------------------------- @@ -847,6 +848,7 @@ int cOsd::osdWidth = 0; int cOsd::osdHeight = 0; int cOsd::isOpen = 0; +bool cOsd::niosd = false; cOsd::cOsd(int Left, int Top) { @@ -867,6 +869,8 @@ delete bitmaps[i]; delete savedRegion; isOpen--; + if (!niosd) + NonInteractiveOsdPatch::OsdController.Show(); } void cOsd::SetOsdPosition(int Left, int Top, int Width, int Height) @@ -1004,8 +1008,11 @@ osdProvider = NULL; } -cOsd *cOsdProvider::NewOsd(int Left, int Top) +cOsd *cOsdProvider::NewOsd(int Left, int Top, bool dontHide) { + if (!dontHide) + NonInteractiveOsdPatch::OsdController.Hide(); + cOsd::niosd = dontHide; if (cOsd::IsOpen()) esyslog("ERROR: attempt to open OSD while it is already open - using dummy OSD!"); else if (osdProvider) diff -Naur vdr-1.5.8.org/osdcontroller.c vdr-1.5.8/osdcontroller.c --- vdr-1.5.8.org/osdcontroller.c 1969-12-31 19:00:00.000000000 -0500 +++ vdr-1.5.8/osdcontroller.c 2008-01-23 18:09:08.254945842 -0500 @@ -0,0 +1,132 @@ +#include "osdcontroller.h" +#include "thread.h" + +namespace NonInteractiveOsdPatch +{ + + class cListenerListObject : public cListObject + { + public: + cListenerListObject(int priority, cOsdListener* listener); + bool operator< (const cListObject &ListObject); + + int iPriority; + cOsdListener* iListener; + }; + + cListenerListObject::cListenerListObject(int priority, cOsdListener* listener) + : cListObject(),iPriority(priority), iListener( listener ) + { + } + bool cListenerListObject::operator< (const cListObject &ListObject) + { + + return iPriority > ((cListenerListObject *)&ListObject)->iPriority; + } + + cOsdController OsdController; + + cOsdController::cOsdController() + : iShowing( false ) + { + iMutex = new cMutex(); + iListeners = new cList; + } + + cOsdController::~cOsdController() + { + delete iListeners; + delete iMutex; + } + + bool cOsdController::Subscribe( int priority, cOsdListener* listener ) + { + + cMutexLock( iMutex ); + if ( !listener ) + return false; + + for ( cListenerListObject* llo = iListeners->First(); + llo; llo = iListeners->Next(llo)) + { + // check for duplicates + if ( llo->iListener == listener ) + return false; + } + + cListenerListObject *lo = new cListenerListObject(priority, listener); + iListeners->Add( lo ); + iListeners->Sort(); + + // Give osd to the new listener if it has higher priority + // than the current one + if ( iShowing && !iCurrent ) + { + listener->Show(); + iCurrent = lo; + } + else if ( iShowing && iCurrent && iCurrent->iPriority < priority ) + { + iCurrent->iListener->Hide(); + ShowHighest(); + + } + + return true; + } + + void cOsdController::Unsubscribe( cOsdListener* listener ) + { + cMutexLock( iMutex ); + if ( !listener ) + return; + + for ( cListenerListObject* llo = iListeners->First(); + llo; llo = iListeners->Next(llo)) + { + + if ( llo->iListener == listener ) + { + iListeners->Del( llo, true ); + if ( iShowing && llo == iCurrent ) + { + listener->Hide(); + ShowHighest(); + } + break; + } + } + + } + + void cOsdController::Show() + { + cMutexLock( iMutex ); + iShowing = true; + ShowHighest(); + + } + + void cOsdController::Hide() + { + cMutexLock( iMutex ); + iShowing = false; + if ( iCurrent ) + iCurrent->iListener->Hide(); + iCurrent = NULL; + } + + void cOsdController::ShowHighest() + { + + cListenerListObject* llo = iListeners->First(); + + if ( llo ) + llo->iListener->Show(); + + iCurrent = llo; + + } + + +} diff -Naur vdr-1.5.8.org/osdcontroller.h vdr-1.5.8/osdcontroller.h --- vdr-1.5.8.org/osdcontroller.h 1969-12-31 19:00:00.000000000 -0500 +++ vdr-1.5.8/osdcontroller.h 2008-01-23 18:09:08.255945914 -0500 @@ -0,0 +1,52 @@ +#ifndef __OSDCONTROLLER_H +#define __OSDCONTROLLER_H + +#include "tools.h" + + +#define MAX_OSD_LISTENERS 10 + +class cOsdProvider; +class cOsd; +class cMutex; + +namespace NonInteractiveOsdPatch +{ + + class cOsdListener + { + + public: + virtual ~cOsdListener() {}; + virtual void Show() = 0; + virtual void Hide() = 0; + + }; + + class cListenerListObject; + + class cOsdController + { + public: + cOsdController(); + ~cOsdController(); + bool Subscribe( int priority, cOsdListener* listener ); + void Unsubscribe( cOsdListener* listner ); + + private: + friend class ::cOsdProvider; + friend class ::cOsd; + void Show(); + void Hide(); + void ShowHighest(); + + bool iShowing; + cMutex* iMutex; + cListenerListObject* iCurrent; + cList* iListeners; + + }; + extern cOsdController OsdController; + +} +#endif diff -Naur vdr-1.5.8.org/osd.h vdr-1.5.8/osd.h --- vdr-1.5.8.org/osd.h 2008-01-23 17:56:06.696263876 -0500 +++ vdr-1.5.8/osd.h 2008-01-23 18:09:08.254945842 -0500 @@ -253,6 +253,8 @@ cBitmap *bitmaps[MAXOSDAREAS]; int numBitmaps; int left, top, width, height; +public: + static bool niosd; protected: cOsd(int Left, int Top); ///< Initializes the OSD with the given coordinates. @@ -388,7 +390,7 @@ cOsdProvider(void); //XXX maybe parameter to make this one "sticky"??? (frame-buffer etc.) virtual ~cOsdProvider(); - static cOsd *NewOsd(int Left, int Top); + static cOsd *NewOsd(int Left, int Top, bool dontHide = false); ///< Returns a pointer to a newly created cOsd object, which will be located ///< at the given coordinates. When the cOsd object is no longer needed, the ///< caller must delete it. If the OSD is already in use, or there is no OSD diff -Naur vdr-1.5.8.org/vdr.c vdr-1.5.8/vdr.c --- vdr-1.5.8.org/vdr.c 2008-01-23 17:33:02.558133681 -0500 +++ vdr-1.5.8/vdr.c 2008-01-23 18:09:08.256945987 -0500 @@ -886,7 +886,7 @@ DeletedRecordings.Update(); } // CAM control: - if (!Menu && !cOsd::IsOpen()) + if (!Menu && !(cOsd::IsOpen() && !cOsd::niosd)) Menu = CamControl(); // Queued messages: if (!Skins.IsOpen()) @@ -912,7 +912,7 @@ if (Menu) DELETE_MENU; else if (cControl::Control()) { - if (cOsd::IsOpen()) + if (cOsd::IsOpen() && !cOsd::niosd) cControl::Control()->Hide(); else WasOpen = false; @@ -1003,7 +1003,7 @@ } else cDevice::PrimaryDevice()->SetVolume(NORMALKEY(key) == kVolDn ? -VOLUMEDELTA : VOLUMEDELTA); - if (!Menu && !cOsd::IsOpen()) + if (!Menu && !(cOsd::IsOpen() && !cOsd::niosd)) Menu = cDisplayVolume::Create(); cDisplayVolume::Process(key); key = kNone; // nobody else needs to see these keys