mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
There can now be more than one OSD at the same time
This commit is contained in:
parent
6a737033ad
commit
a80915ff22
11
HISTORY
11
HISTORY
@ -5380,7 +5380,7 @@ Video Disk Recorder Revision History
|
|||||||
name of the plugin. The "newplugin" script has been changed accordingly, and
|
name of the plugin. The "newplugin" script has been changed accordingly, and
|
||||||
plugin authors should change their Makefiles, too.
|
plugin authors should change their Makefiles, too.
|
||||||
|
|
||||||
2007-08-25: Version 1.5.9
|
2007-08-26: Version 1.5.9
|
||||||
|
|
||||||
- Fixed handling locale directories with a large number of entries (thanks to
|
- Fixed handling locale directories with a large number of entries (thanks to
|
||||||
Anssi Hannula).
|
Anssi Hannula).
|
||||||
@ -5405,3 +5405,12 @@ Video Disk Recorder Revision History
|
|||||||
option ':groups' is given (thanks to Andreas Mair).
|
option ':groups' is given (thanks to Andreas Mair).
|
||||||
- Added a missing error report to cCuttingThread::Action() (thanks to Udo
|
- Added a missing error report to cCuttingThread::Action() (thanks to Udo
|
||||||
Richter).
|
Richter).
|
||||||
|
- There can now be more than one OSD at the same time. At any given time,
|
||||||
|
however, only one of them can be active (and thus visible). This is to
|
||||||
|
allow displaying things like subtitles in an easy way. A cOsd therefore
|
||||||
|
now has a "Level", and only the OSD with the smallest level will be
|
||||||
|
displayed. The level 0 OSD is special, and there can only be one with
|
||||||
|
this level. If there is more than one OSD with a particular level, only
|
||||||
|
the one that was created first will be displayed.
|
||||||
|
Plugins that provide an OSD need to adjust their cOsdProvider::CreateOsd()
|
||||||
|
function to hand through the Level.
|
||||||
|
60
dvbosd.c
60
dvbosd.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: dvbosd.c 1.30 2006/01/28 14:24:04 kls Exp $
|
* $Id: dvbosd.c 1.31 2007/08/26 09:39:20 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dvbosd.h"
|
#include "dvbosd.h"
|
||||||
@ -26,15 +26,17 @@ private:
|
|||||||
int osdMem;
|
int osdMem;
|
||||||
bool shown;
|
bool shown;
|
||||||
void Cmd(OSD_Command cmd, int color = 0, int x0 = 0, int y0 = 0, int x1 = 0, int y1 = 0, const void *data = NULL);
|
void Cmd(OSD_Command cmd, int color = 0, int x0 = 0, int y0 = 0, int x1 = 0, int y1 = 0, const void *data = NULL);
|
||||||
|
protected:
|
||||||
|
virtual void SetActive(bool On);
|
||||||
public:
|
public:
|
||||||
cDvbOsd(int Left, int Top, int OsdDev);
|
cDvbOsd(int Left, int Top, int OsdDev, uint Level);
|
||||||
virtual ~cDvbOsd();
|
virtual ~cDvbOsd();
|
||||||
virtual eOsdError CanHandleAreas(const tArea *Areas, int NumAreas);
|
virtual eOsdError CanHandleAreas(const tArea *Areas, int NumAreas);
|
||||||
virtual void Flush(void);
|
virtual void Flush(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
cDvbOsd::cDvbOsd(int Left, int Top, int OsdDev)
|
cDvbOsd::cDvbOsd(int Left, int Top, int OsdDev, uint Level)
|
||||||
:cOsd(Left, Top)
|
:cOsd(Left, Top, Level)
|
||||||
{
|
{
|
||||||
osdDev = OsdDev;
|
osdDev = OsdDev;
|
||||||
shown = false;
|
shown = false;
|
||||||
@ -49,23 +51,36 @@ cDvbOsd::cDvbOsd(int Left, int Top, int OsdDev)
|
|||||||
if (ioctl(osdDev, OSD_GET_CAPABILITY, &cap) == 0)
|
if (ioctl(osdDev, OSD_GET_CAPABILITY, &cap) == 0)
|
||||||
osdMem = cap.val;
|
osdMem = cap.val;
|
||||||
#endif
|
#endif
|
||||||
// must clear all windows here to avoid flashing effects - doesn't work if done
|
|
||||||
// in Flush() only for the windows that are actually used...
|
|
||||||
for (int i = 0; i < MAXNUMWINDOWS; i++) {
|
|
||||||
Cmd(OSD_SetWindow, 0, i + 1);
|
|
||||||
Cmd(OSD_Clear);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cDvbOsd::~cDvbOsd()
|
cDvbOsd::~cDvbOsd()
|
||||||
{
|
{
|
||||||
if (shown) {
|
SetActive(false);
|
||||||
cBitmap *Bitmap;
|
}
|
||||||
for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) {
|
|
||||||
Cmd(OSD_SetWindow, 0, i + 1);
|
void cDvbOsd::SetActive(bool On)
|
||||||
Cmd(OSD_Close);
|
{
|
||||||
}
|
if (On != Active()) {
|
||||||
|
cOsd::SetActive(On);
|
||||||
|
if (On) {
|
||||||
|
// must clear all windows here to avoid flashing effects - doesn't work if done
|
||||||
|
// in Flush() only for the windows that are actually used...
|
||||||
|
for (int i = 0; i < MAXNUMWINDOWS; i++) {
|
||||||
|
Cmd(OSD_SetWindow, 0, i + 1);
|
||||||
|
Cmd(OSD_Clear);
|
||||||
|
}
|
||||||
|
if (GetBitmap(0)) // only flush here if there are already bitmaps
|
||||||
|
Flush();
|
||||||
|
}
|
||||||
|
else if (shown) {
|
||||||
|
cBitmap *Bitmap;
|
||||||
|
for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) {
|
||||||
|
Cmd(OSD_SetWindow, 0, i + 1);
|
||||||
|
Cmd(OSD_Close);
|
||||||
|
}
|
||||||
|
shown = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,13 +123,20 @@ void cDvbOsd::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1, co
|
|||||||
|
|
||||||
void cDvbOsd::Flush(void)
|
void cDvbOsd::Flush(void)
|
||||||
{
|
{
|
||||||
|
if (!Active())
|
||||||
|
return;
|
||||||
cBitmap *Bitmap;
|
cBitmap *Bitmap;
|
||||||
for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) {
|
for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) {
|
||||||
Cmd(OSD_SetWindow, 0, i + 1);
|
Cmd(OSD_SetWindow, 0, i + 1);
|
||||||
if (!shown)
|
if (!shown)
|
||||||
Cmd(OSD_Open, Bitmap->Bpp(), Left() + Bitmap->X0(), Top() + Bitmap->Y0(), Left() + Bitmap->X0() + Bitmap->Width() - 1, Top() + Bitmap->Y0() + Bitmap->Height() - 1, (void *)1); // initially hidden!
|
Cmd(OSD_Open, Bitmap->Bpp(), Left() + Bitmap->X0(), Top() + Bitmap->Y0(), Left() + Bitmap->X0() + Bitmap->Width() - 1, Top() + Bitmap->Y0() + Bitmap->Height() - 1, (void *)1); // initially hidden!
|
||||||
int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
|
int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
|
||||||
if (Bitmap->Dirty(x1, y1, x2, y2)) {
|
if (!shown || Bitmap->Dirty(x1, y1, x2, y2)) {
|
||||||
|
if (!shown) {
|
||||||
|
x1 = y1 = 0;
|
||||||
|
x2 = Bitmap->Width() - 1;
|
||||||
|
y2 = Bitmap->Height() - 1;
|
||||||
|
}
|
||||||
//TODO Workaround: apparently the bitmap sent to the driver always has to be a multiple
|
//TODO Workaround: apparently the bitmap sent to the driver always has to be a multiple
|
||||||
//TODO of 8 bits wide, and (dx * dy) also has to be a multiple of 8.
|
//TODO of 8 bits wide, and (dx * dy) also has to be a multiple of 8.
|
||||||
//TODO Fix driver (should be able to handle any size bitmaps!)
|
//TODO Fix driver (should be able to handle any size bitmaps!)
|
||||||
@ -173,7 +195,7 @@ cDvbOsdProvider::cDvbOsdProvider(int OsdDev)
|
|||||||
osdDev = OsdDev;
|
osdDev = OsdDev;
|
||||||
}
|
}
|
||||||
|
|
||||||
cOsd *cDvbOsdProvider::CreateOsd(int Left, int Top)
|
cOsd *cDvbOsdProvider::CreateOsd(int Left, int Top, uint Level)
|
||||||
{
|
{
|
||||||
return new cDvbOsd(Left, Top, osdDev);
|
return new cDvbOsd(Left, Top, osdDev, Level);
|
||||||
}
|
}
|
||||||
|
4
dvbosd.h
4
dvbosd.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: dvbosd.h 1.18 2004/06/12 13:09:52 kls Exp $
|
* $Id: dvbosd.h 1.19 2007/08/25 13:49:34 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DVBOSD_H
|
#ifndef __DVBOSD_H
|
||||||
@ -17,7 +17,7 @@ private:
|
|||||||
int osdDev;
|
int osdDev;
|
||||||
public:
|
public:
|
||||||
cDvbOsdProvider(int OsdDev);
|
cDvbOsdProvider(int OsdDev);
|
||||||
virtual cOsd *CreateOsd(int Left, int Top);
|
virtual cOsd *CreateOsd(int Left, int Top, uint Level);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //__DVBOSD_H
|
#endif //__DVBOSD_H
|
||||||
|
43
osd.c
43
osd.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: osd.c 1.73 2007/08/17 15:23:50 kls Exp $
|
* $Id: osd.c 1.74 2007/08/26 09:44:50 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "osd.h"
|
#include "osd.h"
|
||||||
@ -646,18 +646,24 @@ int cOsd::osdLeft = 0;
|
|||||||
int cOsd::osdTop = 0;
|
int cOsd::osdTop = 0;
|
||||||
int cOsd::osdWidth = 0;
|
int cOsd::osdWidth = 0;
|
||||||
int cOsd::osdHeight = 0;
|
int cOsd::osdHeight = 0;
|
||||||
int cOsd::isOpen = 0;
|
cVector<cOsd *> cOsd::Osds;
|
||||||
|
|
||||||
cOsd::cOsd(int Left, int Top)
|
cOsd::cOsd(int Left, int Top, uint Level)
|
||||||
{
|
{
|
||||||
if (isOpen)
|
|
||||||
esyslog("ERROR: OSD opened without closing previous OSD!");
|
|
||||||
savedRegion = NULL;
|
savedRegion = NULL;
|
||||||
numBitmaps = 0;
|
numBitmaps = 0;
|
||||||
left = Left;
|
left = Left;
|
||||||
top = Top;
|
top = Top;
|
||||||
width = height = 0;
|
width = height = 0;
|
||||||
isOpen++;
|
level = Level;
|
||||||
|
active = false;
|
||||||
|
for (int i = 0; i < Osds.Size(); i++) {
|
||||||
|
if (Osds[i]->level > level) {
|
||||||
|
Osds.Insert(this, i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Osds.Append(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
cOsd::~cOsd()
|
cOsd::~cOsd()
|
||||||
@ -665,7 +671,14 @@ cOsd::~cOsd()
|
|||||||
for (int i = 0; i < numBitmaps; i++)
|
for (int i = 0; i < numBitmaps; i++)
|
||||||
delete bitmaps[i];
|
delete bitmaps[i];
|
||||||
delete savedRegion;
|
delete savedRegion;
|
||||||
isOpen--;
|
for (int i = 0; i < Osds.Size(); i++) {
|
||||||
|
if (Osds[i] == this) {
|
||||||
|
Osds.Remove(i);
|
||||||
|
if (Osds.Size())
|
||||||
|
Osds[0]->SetActive(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cOsd::SetOsdPosition(int Left, int Top, int Width, int Height)
|
void cOsd::SetOsdPosition(int Left, int Top, int Width, int Height)
|
||||||
@ -803,15 +816,23 @@ cOsdProvider::~cOsdProvider()
|
|||||||
osdProvider = NULL;
|
osdProvider = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
cOsd *cOsdProvider::NewOsd(int Left, int Top)
|
cOsd *cOsdProvider::NewOsd(int Left, int Top, uint Level)
|
||||||
{
|
{
|
||||||
if (Level == 0 && cOsd::IsOpen())
|
if (Level == 0 && cOsd::IsOpen())
|
||||||
esyslog("ERROR: attempt to open OSD while it is already open - using dummy OSD!");
|
esyslog("ERROR: attempt to open OSD while it is already open - using dummy OSD!");
|
||||||
else if (osdProvider)
|
else if (osdProvider) {
|
||||||
return osdProvider->CreateOsd(Left, Top);
|
cOsd *ActiveOsd = cOsd::Osds.Size() ? cOsd::Osds[0] : NULL;
|
||||||
|
cOsd *Osd = osdProvider->CreateOsd(Left, Top, Level);
|
||||||
|
if (Osd == cOsd::Osds[0]) {
|
||||||
|
if (ActiveOsd)
|
||||||
|
ActiveOsd->SetActive(false);
|
||||||
|
Osd->SetActive(true);
|
||||||
|
}
|
||||||
|
return Osd;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
esyslog("ERROR: no OSD provider available - using dummy OSD!");
|
esyslog("ERROR: no OSD provider available - using dummy OSD!");
|
||||||
return new cOsd(Left, Top); // create a dummy cOsd, so that access won't result in a segfault
|
return new cOsd(Left, Top, 999); // create a dummy cOsd, so that access won't result in a segfault
|
||||||
}
|
}
|
||||||
|
|
||||||
void cOsdProvider::Shutdown(void)
|
void cOsdProvider::Shutdown(void)
|
||||||
|
24
osd.h
24
osd.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: osd.h 1.56 2007/07/20 14:50:17 kls Exp $
|
* $Id: osd.h 1.57 2007/08/26 09:45:38 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __OSD_H
|
#ifndef __OSD_H
|
||||||
@ -15,6 +15,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
#define MAXNUMCOLORS 256
|
#define MAXNUMCOLORS 256
|
||||||
|
|
||||||
@ -247,13 +248,15 @@ class cOsd {
|
|||||||
friend class cOsdProvider;
|
friend class cOsdProvider;
|
||||||
private:
|
private:
|
||||||
static int osdLeft, osdTop, osdWidth, osdHeight;
|
static int osdLeft, osdTop, osdWidth, osdHeight;
|
||||||
static int isOpen;
|
static cVector<cOsd *> Osds;
|
||||||
cBitmap *savedRegion;
|
cBitmap *savedRegion;
|
||||||
cBitmap *bitmaps[MAXOSDAREAS];
|
cBitmap *bitmaps[MAXOSDAREAS];
|
||||||
int numBitmaps;
|
int numBitmaps;
|
||||||
int left, top, width, height;
|
int left, top, width, height;
|
||||||
|
uint level;
|
||||||
|
bool active;
|
||||||
protected:
|
protected:
|
||||||
cOsd(int Left, int Top);
|
cOsd(int Left, int Top, uint Level);
|
||||||
///< Initializes the OSD with the given coordinates.
|
///< Initializes the OSD with the given coordinates.
|
||||||
///< By default it is assumed that the full area will be able to display
|
///< By default it is assumed that the full area will be able to display
|
||||||
///< full 32 bit graphics (ARGB with eight bit for each color and the alpha
|
///< full 32 bit graphics (ARGB with eight bit for each color and the alpha
|
||||||
@ -269,6 +272,14 @@ protected:
|
|||||||
///< and should require only the minimum necessary color depth. This is
|
///< and should require only the minimum necessary color depth. This is
|
||||||
///< because a derived cOsd class may or may not be able to handle more
|
///< because a derived cOsd class may or may not be able to handle more
|
||||||
///< than one area.
|
///< than one area.
|
||||||
|
///< There can be any number of cOsd objects at the same time, but only
|
||||||
|
///< one of them will be active at any given time. The active OSD is the
|
||||||
|
///< one with the lowest value of Level. If there are several cOsd objects
|
||||||
|
///< with the same Level, the one that was created first will be active.
|
||||||
|
bool Active(void) { return active; }
|
||||||
|
virtual void SetActive(bool On) { active = On; }
|
||||||
|
///< Sets this OSD to be the active one.
|
||||||
|
///< A derived class must call cOsd::SetActive(On).
|
||||||
public:
|
public:
|
||||||
virtual ~cOsd();
|
virtual ~cOsd();
|
||||||
///< Shuts down the OSD.
|
///< Shuts down the OSD.
|
||||||
@ -281,7 +292,8 @@ public:
|
|||||||
///< This may be useful for plugins that determine the scaling of the
|
///< This may be useful for plugins that determine the scaling of the
|
||||||
///< video image and need to scale the OSD accordingly to fit on the
|
///< video image and need to scale the OSD accordingly to fit on the
|
||||||
///< screen.
|
///< screen.
|
||||||
static int IsOpen(void) { return isOpen; }
|
static int IsOpen(void) { return Osds.Size() && Osds[0]->level == 0; }
|
||||||
|
///< Returns true if there is currently a level 0 OSD open.
|
||||||
int Left(void) { return left; }
|
int Left(void) { return left; }
|
||||||
int Top(void) { return top; }
|
int Top(void) { return top; }
|
||||||
int Width(void) { return width; }
|
int Width(void) { return width; }
|
||||||
@ -379,14 +391,14 @@ class cOsdProvider {
|
|||||||
private:
|
private:
|
||||||
static cOsdProvider *osdProvider;
|
static cOsdProvider *osdProvider;
|
||||||
protected:
|
protected:
|
||||||
virtual cOsd *CreateOsd(int Left, int Top) = 0;
|
virtual cOsd *CreateOsd(int Left, int Top, uint Level) = 0;
|
||||||
///< Returns a pointer to a newly created cOsd object, which will be located
|
///< Returns a pointer to a newly created cOsd object, which will be located
|
||||||
///< at the given coordinates.
|
///< at the given coordinates.
|
||||||
public:
|
public:
|
||||||
cOsdProvider(void);
|
cOsdProvider(void);
|
||||||
//XXX maybe parameter to make this one "sticky"??? (frame-buffer etc.)
|
//XXX maybe parameter to make this one "sticky"??? (frame-buffer etc.)
|
||||||
virtual ~cOsdProvider();
|
virtual ~cOsdProvider();
|
||||||
static cOsd *NewOsd(int Left, int Top);
|
static cOsd *NewOsd(int Left, int Top, uint Level = 0);
|
||||||
///< Returns a pointer to a newly created cOsd object, which will be located
|
///< 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
|
///< 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
|
///< caller must delete it. If the OSD is already in use, or there is no OSD
|
||||||
|
8
tools.h
8
tools.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: tools.h 1.107 2007/08/05 12:11:52 kls Exp $
|
* $Id: tools.h 1.108 2007/08/25 14:16:39 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TOOLS_H
|
#ifndef __TOOLS_H
|
||||||
@ -464,6 +464,12 @@ public:
|
|||||||
Realloc(allocated * 4 / 2); // increase size by 50%
|
Realloc(allocated * 4 / 2); // increase size by 50%
|
||||||
data[size++] = Data;
|
data[size++] = Data;
|
||||||
}
|
}
|
||||||
|
virtual void Remove(int Index)
|
||||||
|
{
|
||||||
|
if (Index < size - 1)
|
||||||
|
memmove(&data[Index], &data[Index + 1], (size - Index) * sizeof(T));
|
||||||
|
size--;
|
||||||
|
}
|
||||||
virtual void Clear(void) {}
|
virtual void Clear(void) {}
|
||||||
void Sort(__compar_fn_t Compare)
|
void Sort(__compar_fn_t Compare)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user