summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY7
-rw-r--r--Makefile4
-rw-r--r--config.h4
-rw-r--r--dvbosd.c545
-rw-r--r--dvbosd.h171
-rw-r--r--osdbase.c482
-rw-r--r--osdbase.h211
7 files changed, 763 insertions, 661 deletions
diff --git a/HISTORY b/HISTORY
index ff8e834f..361c0cec 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1254,3 +1254,10 @@ Video Disk Recorder Revision History
and '-P' used to load plugins. This first step implements the complete "outer"
shell for plugins. The "inner" access to VDR data structures will follow.
- The VDR version number is now displayed in the title line of the "Setup" menu.
+
+2002-05-10: Version 1.1.1
+
+- Separated the actual DVB hardware OSD implementation from the abstract OSD
+ interface. 'osdbase.c/.h' now implements the abstract OSD, while 'dvbosd.c/.h'
+ is the actual implementation for the DVB hardware. This is in preparation for
+ allowing additional kinds of OSD hardware implementations.
diff --git a/Makefile b/Makefile
index 4759ec24..ea201dad 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@
# See the main source file 'vdr.c' for copyright information and
# how to reach the author.
#
-# $Id: Makefile 1.34 2002/05/09 09:35:05 kls Exp $
+# $Id: Makefile 1.35 2002/05/10 10:24:46 kls Exp $
.DELETE_ON_ERROR:
@@ -22,7 +22,7 @@ INCLUDES = -I$(DVBDIR)/ost/include
DTVLIB = $(DTVDIR)/libdtv.a
OBJS = config.o dvbapi.o dvbosd.o eit.o font.o i18n.o interface.o menu.o\
- menuitems.o osd.o plugin.o recording.o remote.o remux.o ringbuffer.o\
+ menuitems.o osdbase.o osd.o plugin.o recording.o remote.o remux.o ringbuffer.o\
svdrp.o thread.o tools.o vdr.o videodir.o
OSDFONT = -adobe-helvetica-medium-r-normal--23-*-100-100-p-*-iso8859-1
diff --git a/config.h b/config.h
index 0824553d..a11f1fa3 100644
--- a/config.h
+++ b/config.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: config.h 1.113 2002/05/05 12:00:00 kls Exp $
+ * $Id: config.h 1.114 2002/05/10 13:48:00 kls Exp $
*/
#ifndef __CONFIG_H
@@ -19,7 +19,7 @@
#include "eit.h"
#include "tools.h"
-#define VDRVERSION "1.1.0"
+#define VDRVERSION "1.1.1"
#define MAXPRIORITY 99
#define MAXLIFETIME 99
diff --git a/dvbosd.c b/dvbosd.c
index eb962613..227d1ff9 100644
--- a/dvbosd.c
+++ b/dvbosd.c
@@ -1,383 +1,45 @@
/*
- * dvbosd.c: Interface to the DVB On Screen Display
+ * dvbosd.c: Implementation of the DVB On Screen Display
*
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: dvbosd.c 1.13 2002/04/13 11:34:48 kls Exp $
+ * $Id: dvbosd.c 1.14 2002/05/10 14:22:04 kls Exp $
*/
#include "dvbosd.h"
#include <signal.h>
#include <sys/ioctl.h>
-#include <sys/stat.h>
#include <sys/unistd.h>
#include "tools.h"
-// --- cPalette --------------------------------------------------------------
-
-cPalette::cPalette(int Bpp)
-{
- maxColors = 1 << Bpp;
- numColors = 0;
- full = false;
-}
-
-int cPalette::Index(eDvbColor Color)
-{
-#if __BYTE_ORDER == __BIG_ENDIAN
- Color = eDvbColor(((Color & 0xFF) << 24) | ((Color & 0xFF00) << 8) | ((Color & 0xFF0000) >> 8) | ((Color & 0xFF000000) >> 24));
-#endif
- for (int i = 0; i < numColors; i++) {
- if (color[i] == Color) {
- used[i] = true;
- return i;
- }
- }
- if (!full) {
- if (numColors < maxColors) {
- color[numColors++] = Color;
- used[numColors - 1] = true;
- fetched[numColors - 1] = false;
- return numColors - 1;
- }
- for (int i = maxColors; --i >= 0; ) {
- if (!used[i]) {
- color[i] = Color;
- used[i] = true;
- fetched[i] = false;
- return i;
- }
- }
- esyslog(LOG_ERR, "ERROR: too many different colors used in palette");
- full = true;
- }
- return 0;
-}
-
-void cPalette::Reset(void)
-{
- for (int i = 0; i < numColors; i++)
- used[i] = false;
- full = false;
-}
-
-const eDvbColor *cPalette::Colors(int &FirstColor, int &LastColor)
-{
- for (FirstColor = 0; FirstColor < numColors; FirstColor++) {
- if (!fetched[FirstColor]) {
- for (LastColor = FirstColor; LastColor < numColors && !fetched[LastColor]; LastColor++)
- fetched[LastColor] = true;
- LastColor--; // the loop ended one past the last one!
- return &color[FirstColor];
- }
- }
- return NULL;
-}
-
-void cPalette::Take(const cPalette &Palette, tIndexes *Indexes)
-{
- for (int i = 0; i < Palette.numColors; i++) {
- if (Palette.used[i]) {
- int n = Index(Palette.color[i]);
- if (Indexes)
- (*Indexes)[i] = n;
- }
- }
-}
-
-// --- cBitmap ---------------------------------------------------------------
-
-cBitmap::cBitmap(int Width, int Height, int Bpp, bool ClearWithBackground)
-:cPalette(Bpp)
-{
- width = Width;
- height = Height;
- clearWithBackground = ClearWithBackground;
- bitmap = NULL;
- fontType = fontOsd;
- font = NULL;
- if (width > 0 && height > 0) {
- bitmap = new char[width * height];
- if (bitmap) {
- Clean();
- memset(bitmap, 0x00, width * height);
- SetFont(fontOsd);
- }
- else
- esyslog(LOG_ERR, "ERROR: can't allocate bitmap!");
- }
- else
- esyslog(LOG_ERR, "ERROR: illegal bitmap parameters (%d, %d)!", width, height);
-}
-
-cBitmap::~cBitmap()
-{
- delete font;
- delete bitmap;
-}
-
-eDvbFont cBitmap::SetFont(eDvbFont Font)
-{
- eDvbFont oldFont = fontType;
- if (fontType != Font || !font) {
- delete font;
- font = new cFont(Font);
- fontType = Font;
- }
- return oldFont;
-}
-
-bool cBitmap::Dirty(int &x1, int &y1, int &x2, int &y2)
-{
- if (dirtyX2 >= 0) {
- //XXX Workaround: apparently the bitmap sent to the driver always has to be a multiple
- //XXX 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!)
- while ((dirtyX1 > 0 || dirtyX2 < width - 1) && ((dirtyX2 - dirtyX1) & 7) != 7) {
- if (dirtyX2 < width - 1)
- dirtyX2++;
- else if (dirtyX1 > 0)
- dirtyX1--;
- }
- //XXX "... / 2" <==> Bpp???
- while ((dirtyY1 > 0 || dirtyY2 < height - 1) && (((dirtyX2 - dirtyX1 + 1) * (dirtyY2 - dirtyY1 + 1) / 2) & 7) != 0) {
- if (dirtyY2 < height - 1)
- dirtyY2++;
- else if (dirtyY1 > 0)
- dirtyY1--;
- }
- while ((dirtyX1 > 0 || dirtyX2 < width - 1) && (((dirtyX2 - dirtyX1 + 1) * (dirtyY2 - dirtyY1 + 1) / 2) & 7) != 0) {
- if (dirtyX2 < width - 1)
- dirtyX2++;
- else if (dirtyX1 > 0)
- dirtyX1--;
- }
- x1 = dirtyX1;
- y1 = dirtyY1;
- x2 = dirtyX2;
- y2 = dirtyY2;
- return true;
- }
- return false;
-}
-
-void cBitmap::Clean(void)
-{
- dirtyX1 = width;
- dirtyY1 = height;
- dirtyX2 = -1;
- dirtyY2 = -1;
-}
-
-void cBitmap::SetIndex(int x, int y, char Index)
-{
- if (bitmap) {
- if (0 <= x && x < width && 0 <= y && y < height) {
- if (bitmap[width * y + x] != Index) {
- bitmap[width * y + x] = Index;
- if (dirtyX1 > x) dirtyX1 = x;
- if (dirtyY1 > y) dirtyY1 = y;
- if (dirtyX2 < x) dirtyX2 = x;
- if (dirtyY2 < y) dirtyY2 = y;
- }
- }
- }
-}
-
-void cBitmap::SetPixel(int x, int y, eDvbColor Color)
-{
- SetIndex(x, y, Index(Color));
-}
-
-void cBitmap::SetBitmap(int x, int y, const cBitmap &Bitmap)
-{
- if (bitmap && Bitmap.bitmap) {
- tIndexes Indexes;
- Take(Bitmap, &Indexes);
- for (int ix = 0; ix < Bitmap.width; ix++) {
- for (int iy = 0; iy < Bitmap.height; iy++)
- SetIndex(x + ix, y + iy, Indexes[Bitmap.bitmap[Bitmap.width * iy + ix]]);
- }
- }
-}
-
-int cBitmap::Width(unsigned char c)
-{
- return font ? font->Width(c) : -1;
-}
-
-int cBitmap::Width(const char *s)
-{
- return font ? font->Width(s) : -1;
-}
-
-void cBitmap::Text(int x, int y, const char *s, eDvbColor ColorFg, eDvbColor ColorBg)
-{
- if (bitmap) {
- char fg = Index(ColorFg);
- char bg = Index(ColorBg);
- int h = font->Height(s);
- while (s && *s) {
- const cFont::tCharData *CharData = font->CharData(*s++);
- if (int(x + CharData->width) > width)
- break;
- for (int row = 0; row < h; row++) {
- cFont::tPixelData PixelData = CharData->lines[row];
- for (int col = CharData->width; col-- > 0; ) {
- SetIndex(x + col, y + row, (PixelData & 1) ? fg : bg);
- PixelData >>= 1;
- }
- }
- x += CharData->width;
- }
- }
-}
-
-void cBitmap::Fill(int x1, int y1, int x2, int y2, eDvbColor Color)
-{
- if (bitmap) {
- char c = Index(Color);
- for (int y = y1; y <= y2; y++)
- for (int x = x1; x <= x2; x++)
- SetIndex(x, y, c);
- }
-}
-
-void cBitmap::Clear(void)
-{
- Reset();
- if (clearWithBackground)
- Fill(0, 0, width - 1, height - 1, clrBackground);
-}
-
-const char *cBitmap::Data(int x, int y)
-{
- return &bitmap[y * width + x];
-}
-
-// --- cWindow ---------------------------------------------------------------
-
-class cWindow : public cBitmap {
-private:
- int handle; // the index within the OSD's window array (0...MAXNUMWINDOWS - 1)
- int x0, y0;
- int bpp;
- bool tiled;
- bool shown;
-public:
- cWindow(int Handle, int x, int y, int w, int h, int Bpp, bool ClearWithBackground, bool Tiled);
- int X0(void) { return x0; }
- int Y0(void) { return y0; }
- int Bpp(void) { return bpp; }
- bool Tiled(void) { return tiled; }
- bool Shown(void) { bool s = shown; shown = true; return s; }
- int Handle(void) { return handle; }
- bool Contains(int x, int y);
- void Relocate(int x, int y);
- void Fill(int x1, int y1, int x2, int y2, eDvbColor Color);
- void SetBitmap(int x, int y, const cBitmap &Bitmap);
- void Text(int x, int y, const char *s, eDvbColor ColorFg = clrWhite, eDvbColor ColorBg = clrBackground);
- const char *Data(int x, int y);
- };
-
-cWindow::cWindow(int Handle, int x, int y, int w, int h, int Bpp, bool ClearWithBackground, bool Tiled)
-:cBitmap(w, h, Bpp, ClearWithBackground)
-{
- handle = Handle;
- x0 = x;
- y0 = y;
- bpp = Bpp;
- tiled = Tiled;
- shown = false;
-}
-
-bool cWindow::Contains(int x, int y)
-{
- x -= x0;
- y -= y0;
- return x >= 0 && y >= 0 && x < width && y < height;
-}
-
-void cWindow::Relocate(int x, int y)
-{
- x0 = x;
- y0 = y;
-}
-
-void cWindow::Fill(int x1, int y1, int x2, int y2, eDvbColor Color)
-{
- if (tiled) {
- x1 -= x0;
- y1 -= y0;
- x2 -= x0;
- y2 -= y0;
- }
- cBitmap::Fill(x1, y1, x2, y2, Color);
-}
-
-void cWindow::SetBitmap(int x, int y, const cBitmap &Bitmap)
-{
- if (tiled) {
- x -= x0;
- y -= y0;
- }
- cBitmap::SetBitmap(x, y, Bitmap);
-}
-
-void cWindow::Text(int x, int y, const char *s, eDvbColor ColorFg, eDvbColor ColorBg)
-{
- if (tiled) {
- x -= x0;
- y -= y0;
- }
- cBitmap::Text(x, y, s, ColorFg, ColorBg);
-}
-
-const char *cWindow::Data(int x, int y)
-{
- return cBitmap::Data(x, y);
-}
-
-// --- cDvbOsd ---------------------------------------------------------------
-
-cDvbOsd::cDvbOsd(int VideoDev, int x, int y, int w, int h, int Bpp)
+cDvbOsd::cDvbOsd(int VideoDev, int x, int y)
+:cOsd(x, y)
{
videoDev = VideoDev;
- numWindows = 0;
- x0 = x;
- y0 = y;
- if (videoDev >= 0) {
- if (w > 0 && h > 0)
- Create(0, 0, w, h, Bpp);
- }
- else
+ if (videoDev < 0)
esyslog(LOG_ERR, "ERROR: illegal video device handle (%d)!", videoDev);
}
cDvbOsd::~cDvbOsd()
{
- if (videoDev >= 0) {
- for (int i = 0; i < numWindows; i++) {
- SetWindow(window[i]);
- Cmd(OSD_Close);
- delete window[i];
- }
- numWindows = 0;
- }
+ for (int i = 0; i < NumWindows(); i++)
+ CloseWindow(GetWindowNr(i));
}
bool cDvbOsd::SetWindow(cWindow *Window)
{
- // Window handles are counted 0...(MAXNUMWINDOWS - 1), but the actual window
- // numbers in the driver are used from 1...MAXNUMWINDOWS.
- int Handle = Window->Handle();
- if (0 <= Handle && Handle < MAXNUMWINDOWS) {
- Cmd(OSD_SetWindow, 0, Handle + 1);
- return true;
+ if (Window) {
+ // Window handles are counted 0...(MAXNUMWINDOWS - 1), but the actual window
+ // numbers in the driver are used from 1...MAXNUMWINDOWS.
+ int Handle = Window->Handle();
+ if (0 <= Handle && Handle < MAXNUMWINDOWS) {
+ Cmd(OSD_SetWindow, 0, Handle + 1);
+ return true;
+ }
+ esyslog(LOG_ERR, "ERROR: illegal window handle: %d", Handle);
}
- esyslog(LOG_ERR, "ERROR: illegal window handle: %d", Handle);
- return -1;
+ return false;
}
void cDvbOsd::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1, const void *data)
@@ -406,166 +68,51 @@ void cDvbOsd::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1, co
}
}
-tWindowHandle cDvbOsd::Create(int x, int y, int w, int h, int Bpp, bool ClearWithBackground, bool Tiled)
+bool cDvbOsd::OpenWindow(cWindow *Window)
{
- if (numWindows < MAXNUMWINDOWS) {
- if (x >= 0 && y >= 0 && w > 0 && h > 0 && (Bpp == 1 || Bpp == 2 || Bpp == 4 || Bpp == 8)) {
- if ((w & 0x03) != 0) {
- w += 4 - (w & 0x03);
- esyslog(LOG_ERR, "ERROR: OSD window width must be a multiple of 4 - increasing to %d", w);
- }
- cWindow *win = new cWindow(numWindows, x, y, w, h, Bpp, ClearWithBackground, Tiled);
- if (SetWindow(win)) {
- window[win->Handle()] = win;
- Cmd(OSD_Open, Bpp, x0 + x, y0 + y, x0 + x + w - 1, y0 + y + h - 1, (void *)1); // initially hidden!
- numWindows++;
- return win->Handle();
- }
- else
- delete win;
- }
- else
- esyslog(LOG_ERR, "ERROR: illegal OSD parameters");
- }
- else
- esyslog(LOG_ERR, "ERROR: too many OSD windows");
- return -1;
-}
-
-void cDvbOsd::AddColor(eDvbColor Color, tWindowHandle Window)
-{
- cWindow *w = GetWindow(Window);
- if (w) {
- w->Index(Color);
- w->Reset();
+ if (SetWindow(Window)) {
+ Cmd(OSD_Open, Window->Bpp(), X0() + Window->X0(), Y0() + Window->Y0(), X0() + Window->X0() + Window->Width() - 1, Y0() + Window->Y0() + Window->Height() - 1, (void *)1); // initially hidden!
+ return true;
}
+ return false;
}
-cWindow *cDvbOsd::GetWindow(int x, int y)
-{
- for (int i = 0; i < numWindows; i++) {
- if (window[i]->Tiled() && window[i]->Contains(x, y))
- return window[i];
- }
- return NULL;
-}
-
-cWindow *cDvbOsd::GetWindow(tWindowHandle Window)
-{
- if (0 <= Window && Window < numWindows)
- return window[Window];
- if (Window == LAST_CREATED_WINDOW && numWindows > 0)
- return window[numWindows - 1];
- return NULL;
-}
-
-void cDvbOsd::Flush(void)
-{
- for (int i = 0; i < numWindows; i++) {
- int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
- if (window[i]->Dirty(x1, y1, x2, y2)) {
- SetWindow(window[i]);
- int FirstColor = 0, LastColor = 0;
- const eDvbColor *pal;
- while ((pal = window[i]->Colors(FirstColor, LastColor)) != NULL)
- Cmd(OSD_SetPalette, FirstColor, LastColor, 0, 0, 0, pal);
- Cmd(OSD_SetBlock, window[i]->Width(), x1, y1, x2, y2, window[i]->Data(x1, y1));
- window[i]->Clean();
- }
- }
- // Showing the windows in a separate loop to avoid seeing them come up one after another
- for (int i = 0; i < numWindows; i++) {
- if (!window[i]->Shown()) {
- SetWindow(window[i]);
- Cmd(OSD_MoveWindow, 0, x0 + window[i]->X0(), y0 + window[i]->Y0());
- }
- }
-}
-
-void cDvbOsd::Clear(tWindowHandle Window)
+void cDvbOsd::CommitWindow(cWindow *Window)
{
- if (Window == ALL_TILED_WINDOWS || Window == ALL_WINDOWS) {
- for (int i = 0; i < numWindows; i++)
- if (Window == ALL_WINDOWS || window[i]->Tiled())
- window[i]->Clear();
- }
- else {
- cWindow *w = GetWindow(Window);
- if (w)
- w->Clear();
+ if (SetWindow(Window)) {
+ int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
+ if (Window->Dirty(x1, y1, x2, y2)) {
+ // commit colors:
+ int FirstColor = 0, LastColor = 0;
+ const eDvbColor *pal;
+ while ((pal = Window->Colors(FirstColor, LastColor)) != NULL)
+ Cmd(OSD_SetPalette, FirstColor, LastColor, 0, 0, 0, pal);
+ // commit modified data:
+ Cmd(OSD_SetBlock, Window->Width(), x1, y1, x2, y2, Window->Data(x1, y1));
+ }
}
}
-void cDvbOsd::Fill(int x1, int y1, int x2, int y2, eDvbColor Color, tWindowHandle Window)
+void cDvbOsd::ShowWindow(cWindow *Window)
{
- cWindow *w = (Window == ALL_TILED_WINDOWS) ? GetWindow(x1, y1) : GetWindow(Window);
- if (w)
- w->Fill(x1, y1, x2, y2, Color);
+ if (SetWindow(Window))
+ Cmd(OSD_MoveWindow, 0, X0() + Window->X0(), Y0() + Window->Y0());
}
-void cDvbOsd::SetBitmap(int x, int y, const cBitmap &Bitmap, tWindowHandle Window)
+void cDvbOsd::HideWindow(cWindow *Window, bool Hide)
{
- cWindow *w = (Window == ALL_TILED_WINDOWS) ? GetWindow(x, y) : GetWindow(Window);
- if (w)
- w->SetBitmap(x, y, Bitmap);
+ if (SetWindow(Window))
+ Cmd(Hide ? OSD_Hide : OSD_Show, 0);
}
-int cDvbOsd::Width(unsigned char c)
+void cDvbOsd::MoveWindow(cWindow *Window, int x, int y)
{
- return numWindows ? window[0]->Width(c) : 0;
+ if (SetWindow(Window))
+ Cmd(OSD_MoveWindow, 0, X0() + x, Y0() + y);
}
-int cDvbOsd::Width(const char *s)
+void cDvbOsd::CloseWindow(cWindow *Window)
{
- return numWindows ? window[0]->Width(s) : 0;
+ if (SetWindow(Window))
+ Cmd(OSD_Close);
}
-
-eDvbFont cDvbOsd::SetFont(eDvbFont Font)
-{
- eDvbFont oldFont = Font;
- for (int i = 0; i < numWindows; i++)
- oldFont = window[i]->SetFont(Font);
- return oldFont;
-}
-
-void cDvbOsd::Text(int x, int y, const char *s, eDvbColor ColorFg = clrWhite, eDvbColor ColorBg = clrBackground, tWindowHandle Window)
-{
- cWindow *w = (Window == ALL_TILED_WINDOWS) ? GetWindow(x, y) : GetWindow(Window);
- if (w)
- w->Text(x, y, s, ColorFg, ColorBg);
-}
-
-void cDvbOsd::Relocate(tWindowHandle Window, int x, int y, int NewWidth, int NewHeight)
-{
- cWindow *w = GetWindow(Window);
- if (w) {
- SetWindow(w);
- if (NewWidth > 0 && NewHeight > 0) {
- if ((NewWidth & 0x03) != 0) {
- NewWidth += 4 - (NewWidth & 0x03);
- esyslog(LOG_ERR, "ERROR: OSD window width must be a multiple of 4 - increasing to %d", NewWidth);
- }
- Cmd(OSD_Close);
- window[w->Handle()] = new cWindow(w->Handle(), x, y, NewWidth, NewHeight, w->Bpp(), w->ClearWithBackground(), w->Tiled());
- delete w;
- Cmd(OSD_Open, 2, x0 + x, y0 + y, x0 + x + NewWidth - 1, y0 + y + NewHeight - 1, (void *)1); // initially hidden!
- }
- else {
- w->Relocate(x, y);
- Cmd(OSD_MoveWindow, 0, x0 + x, y0 + y);
- }
- }
-}
-
-void cDvbOsd::Hide(tWindowHandle Window)
-{
- if (SetWindow(GetWindow(Window)))
- Cmd(OSD_Hide, 0);
-}
-
-void cDvbOsd::Show(tWindowHandle Window)
-{
- if (SetWindow(GetWindow(Window)))
- Cmd(OSD_Show, 0);
-}
-
diff --git a/dvbosd.h b/dvbosd.h
index 0e90414c..ff26bcff 100644
--- a/dvbosd.h
+++ b/dvbosd.h
@@ -1,178 +1,33 @@
/*
- * dvbosd.h: Interface to the DVB On Screen Display
+ * dvbosd.h: Implementation of the DVB On Screen Display
*
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: dvbosd.h 1.10 2002/02/03 16:43:50 kls Exp $
+ * $Id: dvbosd.h 1.11 2002/05/10 14:22:07 kls Exp $
*/
#ifndef __DVBOSD_H
#define __DVBOSD_H
-#if defined(DEBUG_OSD) || defined(REMOTE_KBD)
-#include <ncurses.h>
-#undef ERR //XXX ncurses defines this - but this clashes with newer system header files
-#endif
#include <ost/osd.h>
-#include <stdio.h>
-#include "font.h"
+#include "osdbase.h"
-#define MAXNUMCOLORS 16
-
-enum eDvbColor {
-#ifdef DEBUG_OSD
- clrBackground,
- clrTransparent = clrBackground,
- clrBlack = clrBackground,
- clrRed,
- clrGreen,
- clrYellow,
- clrBlue,
- clrMagenta,
- clrCyan,
- clrWhite,
-#else
- clrTransparent = 0x00000000,
- clrBackground = 0x7F000000, // 50% gray
- clrBlack = 0xFF000000,
- clrRed = 0xFF1414FC,
- clrGreen = 0xFF24FC24,
- clrYellow = 0xFF24C0FC,
- clrMagenta = 0xFFFC00B0,
- clrBlue = 0xFFFC0000,
- clrCyan = 0xFFFCFC00,
- clrWhite = 0xFFFCFCFC,
-#endif
- };
-
-class cPalette {
-private:
- eDvbColor color[MAXNUMCOLORS];
- int maxColors, numColors;
- bool used[MAXNUMCOLORS];
- bool fetched[MAXNUMCOLORS];
- bool full;
-protected:
- typedef unsigned char tIndexes[MAXNUMCOLORS];
-public:
- cPalette(int Bpp);
- int Index(eDvbColor Color);
- void Reset(void);
- const eDvbColor *Colors(int &FirstColor, int &LastColor);
- void Take(const cPalette &Palette, tIndexes *Indexes = NULL);
- };
-
-class cBitmap : public cPalette {
-private:
- cFont *font;
- eDvbFont fontType;
- void SetIndex(int x, int y, char Index);
- char *bitmap;
- bool clearWithBackground;
-protected:
- int width, height;
- int dirtyX1, dirtyY1, dirtyX2, dirtyY2;
-public:
- cBitmap(int Width, int Height, int Bpp, bool ClearWithBackground = true);
- virtual ~cBitmap();
- bool ClearWithBackground(void) { return clearWithBackground; }
- eDvbFont SetFont(eDvbFont Font);
- bool Dirty(int &x1, int &y1, int &x2, int &y2);
- void SetPixel(int x, int y, eDvbColor Color);
- void SetBitmap(int x, int y, const cBitmap &Bitmap);
- int Width(void) { return width; }
- int Width(unsigned char c);
- int Width(const char *s);
- void Text(int x, int y, const char *s, eDvbColor ColorFg = clrWhite, eDvbColor ColorBg = clrBackground);
- void Fill(int x1, int y1, int x2, int y2, eDvbColor Color);
- void Clean(void);
- void Clear(void);
- const char *Data(int x, int y);
- };
-
-#define MAXNUMWINDOWS 7 // OSD windows are counted 1...7
-
-class cWindow;
-
-typedef int tWindowHandle;
-
-// '-1' is used as an error return value!
-#define ALL_WINDOWS (-2)
-#define ALL_TILED_WINDOWS (-3)
-#define LAST_CREATED_WINDOW (-4)
-
-class cDvbOsd {
+class cDvbOsd : public cOsd {
private:
int videoDev;
- int numWindows;
- int x0, y0;
- cWindow *window[MAXNUMWINDOWS];
bool SetWindow(cWindow *Window);
void Cmd(OSD_Command cmd, int color = 0, int x0 = 0, int y0 = 0, int x1 = 0, int y1 = 0, const void *data = NULL);
- cWindow *GetWindow(int x, int y);
- cWindow *GetWindow(tWindowHandle Window);
+protected:
+ virtual bool OpenWindow(cWindow *Window);
+ virtual void CommitWindow(cWindow *Window);
+ virtual void ShowWindow(cWindow *Window);
+ virtual void HideWindow(cWindow *Window, bool Hide);
+ virtual void MoveWindow(cWindow *Window, int x, int y);
+ virtual void CloseWindow(cWindow *Window);
public:
- cDvbOsd(int VideoDev, int x, int y, int w = -1, int h = -1, int Bpp = -1);
- // Initializes the OSD on the given VideoDev, starting at screen coordinates
- // (x, y). If w, h and Bpp are given, one window with that width, height and
- // color depth will be created - otherwise the actual windows will have to
- // be created by separate calls to Create().
- ~cDvbOsd();
- // Destroys all windows and shuts down the OSD.
- tWindowHandle Create(int x, int y, int w, int h, int Bpp, bool ClearWithBackground = true, bool Tiled = true);
- // Creates a window at coordinates (x, y), which are relative to the OSD's
- // origin given in the constructor, with the given width, height and color
- // depth. ClearWithBackground controls whether the window will be filled with
- // clrBackground when it is cleared. Setting this to 'false' may be useful
- // for windows that don't need clrBackground but want to save this color
- // palette entry for a different color. Tiled controls whether this will
- // be part of a multi section OSD (with several windows that all have
- // different color depths and palettes and form one large OSD area), or
- // whether this is a "standalone" window that will be drawn "in front"
- // of any windows defined *after* this one (this can be used for highlighting
- // certain parts of the OSD, as would be done in a 'cursor').
- // Returns a handle that can be used to identify this window.
- void AddColor(eDvbColor Color, tWindowHandle Window = LAST_CREATED_WINDOW);
- // Adds the Color to the color palette of the given window if it is not
- // already contained in the palette (and if the palette still has free
- // slots for new colors). The default value LAST_CREATED_WINDOW will
- // access the most recently created window, without the need of explicitly
- // using a window handle.
- void Flush(void);
- // Actually commits all data of all windows to the OSD.
- void Clear(tWindowHandle Window = ALL_TILED_WINDOWS);
- // Clears the given window. If ALL_TILED_WINDOWS is given, only the tiled
- // windows will be cleared, leaving the standalone windows untouched. If
- // ALL_WINDOWS is given, the standalone windows will also be cleared.
- void Fill(int x1, int y1, int x2, int y2, eDvbColor Color, tWindowHandle Window = ALL_TILED_WINDOWS);
- // Fills the rectangle defined by the upper left (x1, y2) and lower right
- // (x2, y2) corners with the given Color. If a specific window is given,
- // the coordinates are relative to that window's upper left corner.
- // Otherwise they are relative to the upper left corner of the entire OSD.
- // If all tiled windows are selected, only that window which contains the
- // point (x1, y1) will actually be filled.
- void SetBitmap(int x, int y, const cBitmap &Bitmap, tWindowHandle Window = ALL_TILED_WINDOWS);
- // Sets the pixels within the given window with the data from the given
- // Bitmap. See Fill() for details about the coordinates.
- int Width(unsigned char c);
- // Returns the width (in pixels) of the given character in the current font.
- int Width(const char *s);
- // Returns the width (in pixels) of the given string in the current font.
- eDvbFont SetFont(eDvbFont Font);
- // Sets the current font for subsequent Width() and Text() operations.
- void Text(int x, int y, const char *s, eDvbColor ColorFg = clrWhite, eDvbColor ColorBg = clrBackground, tWindowHandle Window = ALL_TILED_WINDOWS);
- // Writes the given string at coordinates (x, y) with the given foreground
- // and background color into the given window (see Fill() for details
- // about the coordinates).
- void Relocate(tWindowHandle Window, int x, int y, int NewWidth = -1, int NewHeight = -1);
- // Moves the given window to the new location at (x, y). If NewWidth and
- // NewHeight are also given, the window will also be resized to the new
- // width and height.
- void Hide(tWindowHandle Window);
- // Hides the given window.
- void Show(tWindowHandle Window);
- // Shows the given window.
+ cDvbOsd(int VideoDev, int x, int y);
+ virtual ~cDvbOsd();
};
#endif //__DVBOSD_H
diff --git a/osdbase.c b/osdbase.c
new file mode 100644
index 00000000..31e86def
--- /dev/null
+++ b/osdbase.c
@@ -0,0 +1,482 @@
+/*
+ * osdbase.c: Basic interface to the On Screen Display
+ *
+ * See the main source file 'vdr.c' for copyright information and
+ * how to reach the author.
+ *
+ * $Id: osdbase.c 1.1 2002/05/10 14:55:53 kls Exp $
+ */
+
+#include "osdbase.h"
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/unistd.h>
+#include "tools.h"
+
+// --- cPalette --------------------------------------------------------------
+
+cPalette::cPalette(int Bpp)
+{
+ maxColors = 1 << Bpp;
+ numColors = 0;
+ full = false;
+}
+
+int cPalette::Index(eDvbColor Color)
+{
+#if __BYTE_ORDER == __BIG_ENDIAN
+ Color = eDvbColor(((Color & 0xFF) << 24) | ((Color & 0xFF00) << 8) | ((Color & 0xFF0000) >> 8) | ((Color & 0xFF000000) >> 24));
+#endif
+ for (int i = 0; i < numColors; i++) {
+ if (color[i] == Color) {
+ used[i] = true;
+ return i;
+ }
+ }
+ if (!full) {
+ if (numColors < maxColors) {
+ color[numColors++] = Color;
+ used[numColors - 1] = true;
+ fetched[numColors - 1] = false;
+ return numColors - 1;
+ }
+ for (int i = maxColors; --i >= 0; ) {
+ if (!used[i]) {
+ color[i] = Color;
+ used[i] = true;
+ fetched[i] = false;
+ return i;
+ }
+ }
+ esyslog(LOG_ERR, "ERROR: too many different colors used in palette");
+ full = true;
+ }
+ return 0;
+}
+
+void cPalette::Reset(void)
+{
+ for (int i = 0; i < numColors; i++)
+ used[i] = false;
+ full = false;
+}
+
+const eDvbColor *cPalette::Colors(int &FirstColor, int &LastColor)
+{
+ for (FirstColor = 0; FirstColor < numColors; FirstColor++) {
+ if (!fetched[FirstColor]) {
+ for (LastColor = FirstColor; LastColor < numColors && !fetched[LastColor]; LastColor++)
+ fetched[LastColor] = true;
+ LastColor--; // the loop ended one past the last one!
+ return &color[FirstColor];
+ }
+ }
+ return NULL;
+}
+
+void cPalette::Take(const cPalette &Palette, tIndexes *Indexes)
+{
+ for (int i = 0; i < Palette.numColors; i++) {
+ if (Palette.used[i]) {
+ int n = Index(Palette.color[i]);
+ if (Indexes)
+ (*Indexes)[i] = n;
+ }
+ }
+}
+
+// --- cBitmap ---------------------------------------------------------------
+
+cBitmap::cBitmap(int Width, int Height, int Bpp, bool ClearWithBackground)
+:cPalette(Bpp)
+{
+ width = Width;
+ height = Height;
+ clearWithBackground = ClearWithBackground;
+ bitmap = NULL;
+ fontType = fontOsd;
+ font = NULL;
+ if (width > 0 && height > 0) {
+ bitmap = new char[width * height];
+ if (bitmap) {
+ Clean();
+ memset(bitmap, 0x00, width * height);
+ SetFont(fontOsd);
+ }
+ else
+ esyslog(LOG_ERR, "ERROR: can't allocate bitmap!");
+ }
+ else
+ esyslog(LOG_ERR, "ERROR: illegal bitmap parameters (%d, %d)!", width, height);
+}
+
+cBitmap::~cBitmap()
+{
+ delete font;
+ delete bitmap;
+}
+
+eDvbFont cBitmap::SetFont(eDvbFont Font)
+{
+ eDvbFont oldFont = fontType;
+ if (fontType != Font || !font) {
+ delete font;
+ font = new cFont(Font);
+ fontType = Font;
+ }
+ return oldFont;
+}
+
+bool cBitmap::Dirty(int &x1, int &y1, int &x2, int &y2)
+{
+ if (dirtyX2 >= 0) {
+ //XXX Workaround: apparently the bitmap sent to the driver always has to be a multiple
+ //XXX 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!)
+ while ((dirtyX1 > 0 || dirtyX2 < width - 1) && ((dirtyX2 - dirtyX1) & 7) != 7) {
+ if (dirtyX2 < width - 1)
+ dirtyX2++;
+ else if (dirtyX1 > 0)
+ dirtyX1--;
+ }
+ //XXX "... / 2" <==> Bpp???
+ while ((dirtyY1 > 0 || dirtyY2 < height - 1) && (((dirtyX2 - dirtyX1 + 1) * (dirtyY2 - dirtyY1 + 1) / 2) & 7) != 0) {
+ if (dirtyY2 < height - 1)
+ dirtyY2++;
+ else if (dirtyY1 > 0)
+ dirtyY1--;
+ }
+ while ((dirtyX1 > 0 || dirtyX2 < width - 1) && (((dirtyX2 - dirtyX1 + 1) * (dirtyY2 - dirtyY1 + 1) / 2) & 7) != 0) {
+ if (dirtyX2 < width - 1)
+ dirtyX2++;
+ else if (dirtyX1 > 0)
+ dirtyX1--;
+ }
+ x1 = dirtyX1;
+ y1 = dirtyY1;
+ x2 = dirtyX2;
+ y2 = dirtyY2;
+ return true;
+ }
+ return false;
+}
+
+void cBitmap::Clean(void)
+{
+ dirtyX1 = width;
+ dirtyY1 = height;
+ dirtyX2 = -1;
+ dirtyY2 = -1;
+}
+
+void cBitmap::SetIndex(int x, int y, char Index)
+{
+ if (bitmap) {
+ if (0 <= x && x < width && 0 <= y && y < height) {
+ if (bitmap[width * y + x] != Index) {
+ bitmap[width * y + x] = Index;
+ if (dirtyX1 > x) dirtyX1 = x;
+ if (dirtyY1 > y) dirtyY1 = y;
+ if (dirtyX2 < x) dirtyX2 = x;
+ if (dirtyY2 < y) dirtyY2 = y;
+ }
+ }
+ }
+}
+
+void cBitmap::SetPixel(int x, int y, eDvbColor Color)
+{
+ SetIndex(x, y, Index(Color));
+}
+
+void cBitmap::SetBitmap(int x, int y, const cBitmap &Bitmap)
+{
+ if (bitmap && Bitmap.bitmap) {
+ tIndexes Indexes;
+ Take(Bitmap, &Indexes);
+ for (int ix = 0; ix < Bitmap.width; ix++) {
+ for (int iy = 0; iy < Bitmap.height; iy++)
+ SetIndex(x + ix, y + iy, Indexes[Bitmap.bitmap[Bitmap.width * iy + ix]]);
+ }
+ }
+}
+
+int cBitmap::Width(unsigned char c)
+{
+ return font ? font->Width(c) : -1;
+}
+
+int cBitmap::Width(const char *s)
+{
+ return font ? font->Width(s) : -1;
+}
+
+void cBitmap::Text(int x, int y, const char *s, eDvbColor ColorFg, eDvbColor ColorBg)
+{
+ if (bitmap) {
+ char fg = Index(ColorFg);
+ char bg = Index(ColorBg);
+ int h = font->Height(s);
+ while (s && *s) {
+ const cFont::tCharData *CharData = font->CharData(*s++);
+ if (int(x + CharData->width) > width)
+ break;
+ for (int row = 0; row < h; row++) {
+ cFont::tPixelData PixelData = CharData->lines[row];
+ for (int col = CharData->width; col-- > 0; ) {
+ SetIndex(x + col, y + row, (PixelData & 1) ? fg : bg);
+ PixelData >>= 1;
+ }
+ }
+ x += CharData->width;
+ }
+ }
+}
+
+void cBitmap::Fill(int x1, int y1, int x2, int y2, eDvbColor Color)
+{
+ if (bitmap) {
+ char c = Index(Color);
+ for (int y = y1; y <= y2; y++)
+ for (int x = x1; x <= x2; x++)
+ SetIndex(x, y, c);
+ }
+}
+
+void cBitmap::Clear(void)
+{
+ Reset();
+ if (clearWithBackground)
+ Fill(0, 0, width - 1, height - 1, clrBackground);
+}
+
+const char *cBitmap::Data(int x, int y)
+{
+ return &bitmap[y * width + x];
+}
+
+// --- cWindow ---------------------------------------------------------------
+
+cWindow::cWindow(int Handle, int x, int y, int w, int h, int Bpp, bool ClearWithBackground, bool Tiled)
+:cBitmap(w, h, Bpp, ClearWithBackground)
+{
+ handle = Handle;
+ x0 = x;
+ y0 = y;
+ bpp = Bpp;
+ tiled = Tiled;
+ shown = false;
+}
+
+bool cWindow::Contains(int x, int y)
+{
+ x -= x0;
+ y -= y0;
+ return x >= 0 && y >= 0 && x < width && y < height;
+}
+
+void cWindow::Relocate(int x, int y)
+{
+ x0 = x;
+ y0 = y;
+}
+
+void cWindow::Fill(int x1, int y1, int x2, int y2, eDvbColor Color)
+{
+ if (tiled) {
+ x1 -= x0;
+ y1 -= y0;
+ x2 -= x0;
+ y2 -= y0;
+ }
+ cBitmap::Fill(x1, y1, x2, y2, Color);
+}
+
+void cWindow::SetBitmap(int x, int y, const cBitmap &Bitmap)
+{
+ if (tiled) {
+ x -= x0;
+ y -= y0;
+ }
+ cBitmap::SetBitmap(x, y, Bitmap);
+}
+
+void cWindow::Text(int x, int y, const char *s, eDvbColor ColorFg, eDvbColor ColorBg)
+{
+ if (tiled) {
+ x -= x0;
+ y -= y0;
+ }
+ cBitmap::Text(x, y, s, ColorFg, ColorBg);
+}
+
+const char *cWindow::Data(int x, int y)
+{
+ return cBitmap::Data(x, y);
+}
+
+// --- cOsd ------------------------------------------------------------------
+
+cOsd::cOsd(int x, int y)
+{
+ numWindows = 0;
+ x0 = x;
+ y0 = y;
+}
+
+cOsd::~cOsd()
+{
+ for (int i = 0; i < numWindows; i++)
+ delete window[i];
+}
+
+tWindowHandle cOsd::Create(int x, int y, int w, int h, int Bpp, bool ClearWithBackground, bool Tiled)
+{
+ if (numWindows < MAXNUMWINDOWS) {
+ if (x >= 0 && y >= 0 && w > 0 && h > 0 && (Bpp == 1 || Bpp == 2 || Bpp == 4 || Bpp == 8)) {
+ if ((w & 0x03) != 0) {
+ w += 4 - (w & 0x03);
+ esyslog(LOG_ERR, "ERROR: OSD window width must be a multiple of 4 - increasing to %d", w);
+ }
+ cWindow *win = new cWindow(numWindows, x, y, w, h, Bpp, ClearWithBackground, Tiled);
+ if (OpenWindow(win)) {
+ window[win->Handle()] = win;
+ numWindows++;
+ return win->Handle();
+ }
+ else
+ delete win;
+ }
+ else
+ esyslog(LOG_ERR, "ERROR: illegal OSD parameters");
+ }
+ else
+ esyslog(LOG_ERR, "ERROR: too many OSD windows");
+ return -1;
+}
+
+void cOsd::AddColor(eDvbColor Color, tWindowHandle Window)
+{
+ cWindow *w = GetWindow(Window);
+ if (w) {
+ w->Index(Color);
+ w->Reset();
+ }
+}
+
+cWindow *cOsd::GetWindow(int x, int y)
+{
+ for (int i = 0; i < numWindows; i++) {
+ if (window[i]->Tiled() && window[i]->Contains(x, y))
+ return window[i];
+ }
+ return NULL;
+}
+
+cWindow *cOsd::GetWindow(tWindowHandle Window)
+{
+ if (0 <= Window && Window < numWindows)
+ return window[Window];
+ if (Window == LAST_CREATED_WINDOW && numWindows > 0)
+ return window[numWindows - 1];
+ return NULL;
+}
+
+void cOsd::Flush(void)
+{
+ for (int i = 0; i < numWindows; i++) {
+ CommitWindow(window[i]);
+ window[i]->Clean();
+ }
+ // Showing the windows in a separate loop to avoid seeing them come up one after another
+ for (int i = 0; i < numWindows; i++) {
+ if (!window[i]->Shown())
+ ShowWindow(window[i]);
+ }
+}
+
+void cOsd::Clear(tWindowHandle Window)
+{
+ if (Window == ALL_TILED_WINDOWS || Window == ALL_WINDOWS) {
+ for (int i = 0; i < numWindows; i++)
+ if (Window == ALL_WINDOWS || window[i]->Tiled())
+ window[i]->Clear();
+ }
+ else {
+ cWindow *w = GetWindow(Window);
+ if (w)
+ w->Clear();
+ }
+}
+
+void cOsd::Fill(int x1, int y1, int x2, int y2, eDvbColor Color, tWindowHandle Window)
+{
+ cWindow *w = (Window == ALL_TILED_WINDOWS) ? GetWindow(x1, y1) : GetWindow(Window);
+ if (w)
+ w->Fill(x1, y1, x2, y2, Color);
+}
+
+void cOsd::SetBitmap(int x, int y, const cBitmap &Bitmap, tWindowHandle Window)
+{
+ cWindow *w = (Window == ALL_TILED_WINDOWS) ? GetWindow(x, y) : GetWindow(Window);
+ if (w)
+ w->SetBitmap(x, y, Bitmap);
+}
+
+int cOsd::Width(unsigned char c)
+{
+ return numWindows ? window[0]->Width(c) : 0;
+}
+
+int cOsd::Width(const char *s)
+{
+ return numWindows ? window[0]->Width(s) : 0;
+}
+
+eDvbFont cOsd::SetFont(eDvbFont Font)
+{
+ eDvbFont oldFont = Font;
+ for (int i = 0; i < numWindows; i++)
+ oldFont = window[i]->SetFont(Font);
+ return oldFont;
+}
+
+void cOsd::Text(int x, int y, const char *s, eDvbColor ColorFg = clrWhite, eDvbColor ColorBg = clrBackground, tWindowHandle Window)
+{
+ cWindow *w = (Window == ALL_TILED_WINDOWS) ? GetWindow(x, y) : GetWindow(Window);
+ if (w)
+ w->Text(x, y, s, ColorFg, ColorBg);
+}
+
+void cOsd::Relocate(tWindowHandle Window, int x, int y, int NewWidth, int NewHeight)
+{
+ cWindow *w = GetWindow(Window);
+ if (w) {
+ if (NewWidth > 0 && NewHeight > 0) {
+ if ((NewWidth & 0x03) != 0) {
+ NewWidth += 4 - (NewWidth & 0x03);
+ esyslog(LOG_ERR, "ERROR: OSD window width must be a multiple of 4 - increasing to %d", NewWidth);
+ }
+ CloseWindow(w);
+ cWindow *NewWindow = new cWindow(w->Handle(), x, y, NewWidth, NewHeight, w->Bpp(), w->ClearWithBackground(), w->Tiled());
+ window[w->Handle()] = NewWindow;
+ delete w;
+ OpenWindow(NewWindow);
+ }
+ else {
+ MoveWindow(w, x, y);
+ w->Relocate(x, y);
+ }
+ }
+}
+
+void cOsd::Hide(tWindowHandle Window)
+{
+ HideWindow(GetWindow(Window), true);
+}
+
+void cOsd::Show(tWindowHandle Window)
+{
+ HideWindow(GetWindow(Window), false);
+}
diff --git a/osdbase.h b/osdbase.h
new file mode 100644
index 00000000..859939bd
--- /dev/null
+++ b/osdbase.h
@@ -0,0 +1,211 @@
+/*
+ * osdbase.h: Basic interface to the On Screen Display
+ *
+ * See the main source file 'vdr.c' for copyright information and
+ * how to reach the author.
+ *
+ * $Id: osdbase.h 1.1 2002/05/10 14:26:09 kls Exp $
+ */
+
+#ifndef __OSDBASE_H
+#define __OSDBASE_H
+
+#include <stdio.h>
+#include "font.h"
+
+#define MAXNUMCOLORS 16
+
+enum eDvbColor {
+#ifdef DEBUG_OSD
+ clrBackground,
+ clrTransparent = clrBackground,
+ clrBlack = clrBackground,
+ clrRed,
+ clrGreen,
+ clrYellow,
+ clrBlue,
+ clrMagenta,
+ clrCyan,
+ clrWhite,
+#else
+ clrTransparent = 0x00000000,
+ clrBackground = 0x7F000000, // 50% gray
+ clrBlack = 0xFF000000,
+ clrRed = 0xFF1414FC,
+ clrGreen = 0xFF24FC24,
+ clrYellow = 0xFF24C0FC,
+ clrMagenta = 0xFFFC00B0,
+ clrBlue = 0xFFFC0000,
+ clrCyan = 0xFFFCFC00,
+ clrWhite = 0xFFFCFCFC,
+#endif
+ };
+
+class cPalette {
+private:
+ eDvbColor color[MAXNUMCOLORS];
+ int maxColors, numColors;
+ bool used[MAXNUMCOLORS];
+ bool fetched[MAXNUMCOLORS];
+ bool full;
+protected:
+ typedef unsigned char tIndexes[MAXNUMCOLORS];
+public:
+ cPalette(int Bpp);
+ int Index(eDvbColor Color);
+ void Reset(void);
+ const eDvbColor *Colors(int &FirstColor, int &LastColor);
+ void Take(const cPalette &Palette, tIndexes *Indexes = NULL);
+ };
+
+class cBitmap : public cPalette {
+private:
+ cFont *font;
+ eDvbFont fontType;
+ void SetIndex(int x, int y, char Index);
+ char *bitmap;
+ bool clearWithBackground;
+protected:
+ int width, height;
+ int dirtyX1, dirtyY1, dirtyX2, dirtyY2;
+public:
+ cBitmap(int Width, int Height, int Bpp, bool ClearWithBackground = true);
+ virtual ~cBitmap();
+ bool ClearWithBackground(void) { return clearWithBackground; }
+ eDvbFont SetFont(eDvbFont Font);
+ bool Dirty(int &x1, int &y1, int &x2, int &y2);
+ void SetPixel(int x, int y, eDvbColor Color);
+ void SetBitmap(int x, int y, const cBitmap &Bitmap);
+ int Width(void) { return width; }
+ int Width(unsigned char c);
+ int Width(const char *s);
+ int Height(void) { return height; }
+ void Text(int x, int y, const char *s, eDvbColor ColorFg = clrWhite, eDvbColor ColorBg = clrBackground);
+ void Fill(int x1, int y1, int x2, int y2, eDvbColor Color);
+ void Clean(void);
+ void Clear(void);
+ const char *Data(int x, int y);
+ };
+
+#define MAXNUMWINDOWS 7 // OSD windows are counted 1...7
+
+class cWindow : public cBitmap {
+private:
+ int handle; // the index within the OSD's window array (0...MAXNUMWINDOWS - 1)
+ int x0, y0;
+ int bpp;
+ bool tiled;
+ bool shown;
+public:
+ cWindow(int Handle, int x, int y, int w, int h, int Bpp, bool ClearWithBackground, bool Tiled);
+ int X0(void) { return x0; }
+ int Y0(void) { return y0; }
+ int Bpp(void) { return bpp; }
+ bool Tiled(void) { return tiled; }
+ bool Shown(void) { bool s = shown; shown = true; return s; }
+ int Handle(void) { return handle; }
+ bool Contains(int x, int y);
+ void Relocate(int x, int y);
+ void Fill(int x1, int y1, int x2, int y2, eDvbColor Color);
+ void SetBitmap(int x, int y, const cBitmap &Bitmap);
+ void Text(int x, int y, const char *s, eDvbColor ColorFg = clrWhite, eDvbColor ColorBg = clrBackground);
+ const char *Data(int x, int y);
+ };
+
+typedef int tWindowHandle;
+
+// '-1' is used as an error return value!
+#define ALL_WINDOWS (-2)
+#define ALL_TILED_WINDOWS (-3)
+#define LAST_CREATED_WINDOW (-4)
+
+class cOsd {
+private:
+ int numWindows;
+ int x0, y0;
+ cWindow *window[MAXNUMWINDOWS];
+ cWindow *GetWindow(int x, int y);
+ cWindow *GetWindow(tWindowHandle Window);
+protected:
+ cWindow *GetWindowNr(int i) { return i < MAXNUMWINDOWS ? window[i] : NULL; }
+ int NumWindows(void) { return numWindows; }
+ int X0(void) { return x0; }
+ int Y0(void) { return y0; }
+ virtual bool OpenWindow(cWindow *Window) = 0;
+ // Opens the window on the OSD hardware, without actually showing it (the
+ // initial state shall be "hidden").
+ virtual void CommitWindow(cWindow *Window) = 0;
+ // Write any modified data and color definitions to the OSD hardware.
+ // Use the window's Dirty() function to find out which area of data
+ // actually needs to be transferred. If the window has not yet been explicitly
+ // shown through a call to ShowWindow(), no visible activity shall take place.
+ virtual void ShowWindow(cWindow *Window) = 0;
+ // Make the window actually visible on the OSD hardware.
+ virtual void HideWindow(cWindow *Window, bool Hide) = 0;
+ // Temporarily hide the window (if 'Hide' is 'true') or make a previously
+ // hidden window visible again (if 'Hide' is 'false').
+ virtual void MoveWindow(cWindow *Window, int x, int y) = 0;
+ // Move the window to a new location.
+ virtual void CloseWindow(cWindow *Window) = 0;
+ // Close the window and release any OSD hardware resources allocated for it.
+public:
+ cOsd(int x, int y);
+ // Initializes the OSD, starting at screen coordinates (x, y).
+ virtual ~cOsd();
+ // Destroys all windows and shuts down the OSD.
+ tWindowHandle Create(int x, int y, int w, int h, int Bpp, bool ClearWithBackground = true, bool Tiled = true);
+ // Creates a window at coordinates (x, y), which are relative to the OSD's
+ // origin given in the constructor, with the given width, height and color
+ // depth. ClearWithBackground controls whether the window will be filled with
+ // clrBackground when it is cleared. Setting this to 'false' may be useful
+ // for windows that don't need clrBackground but want to save this color
+ // palette entry for a different color. Tiled controls whether this will
+ // be part of a multi section OSD (with several windows that all have
+ // different color depths and palettes and form one large OSD area), or
+ // whether this is a "standalone" window that will be drawn "in front"
+ // of any windows defined *after* this one (this can be used for highlighting
+ // certain parts of the OSD, as would be done in a 'cursor').
+ // Returns a handle that can be used to identify this window.
+ void AddColor(eDvbColor Color, tWindowHandle Window = LAST_CREATED_WINDOW);
+ // Adds the Color to the color palette of the given window if it is not
+ // already contained in the palette (and if the palette still has free
+ // slots for new colors). The default value LAST_CREATED_WINDOW will
+ // access the most recently created window, without the need of explicitly
+ // using a window handle.
+ void Flush(void);
+ // Actually commits all data of all windows to the OSD.
+ void Clear(tWindowHandle Window = ALL_TILED_WINDOWS);
+ // Clears the given window. If ALL_TILED_WINDOWS is given, only the tiled
+ // windows will be cleared, leaving the standalone windows untouched. If
+ // ALL_WINDOWS is given, the standalone windows will also be cleared.
+ void Fill(int x1, int y1, int x2, int y2, eDvbColor Color, tWindowHandle Window = ALL_TILED_WINDOWS);
+ // Fills the rectangle defined by the upper left (x1, y2) and lower right
+ // (x2, y2) corners with the given Color. If a specific window is given,
+ // the coordinates are relative to that window's upper left corner.
+ // Otherwise they are relative to the upper left corner of the entire OSD.
+ // If all tiled windows are selected, only that window which contains the
+ // point (x1, y1) will actually be filled.
+ void SetBitmap(int x, int y, const cBitmap &Bitmap, tWindowHandle Window = ALL_TILED_WINDOWS);
+ // Sets the pixels within the given window with the data from the given
+ // Bitmap. See Fill() for details about the coordinates.
+ int Width(unsigned char c);
+ // Returns the width (in pixels) of the given character in the current font.
+ int Width(const char *s);
+ // Returns the width (in pixels) of the given string in the current font.
+ eDvbFont SetFont(eDvbFont Font);
+ // Sets the current font for subsequent Width() and Text() operations.
+ void Text(int x, int y, const char *s, eDvbColor ColorFg = clrWhite, eDvbColor ColorBg = clrBackground, tWindowHandle Window = ALL_TILED_WINDOWS);
+ // Writes the given string at coordinates (x, y) with the given foreground
+ // and background color into the given window (see Fill() for details
+ // about the coordinates).
+ void Relocate(tWindowHandle Window, int x, int y, int NewWidth = -1, int NewHeight = -1);
+ // Moves the given window to the new location at (x, y). If NewWidth and
+ // NewHeight are also given, the window will also be resized to the new
+ // width and height.
+ void Hide(tWindowHandle Window);
+ // Hides the given window.
+ void Show(tWindowHandle Window);
+ // Shows the given window.
+ };
+
+#endif //__OSDBASE_H