From 37f89dca4967856b0b780fdfa68b30296968be61 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Fri, 10 May 2002 14:55:53 +0200 Subject: [PATCH] Separated the actual DVB hardware OSD implementation from the abstract OSD interface --- HISTORY | 7 + Makefile | 4 +- config.h | 4 +- dvbosd.c | 553 +++++------------------------------------------------- dvbosd.h | 171 ++--------------- osdbase.c | 482 +++++++++++++++++++++++++++++++++++++++++++++++ osdbase.h | 211 +++++++++++++++++++++ 7 files changed, 767 insertions(+), 665 deletions(-) create mode 100644 osdbase.c create mode 100644 osdbase.h 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 #include -#include #include #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"); + 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; } - else - esyslog(LOG_ERR, "ERROR: too many OSD windows"); - return -1; + return false; } -void cDvbOsd::AddColor(eDvbColor Color, tWindowHandle Window) +void cDvbOsd::CommitWindow(cWindow *Window) { - cWindow *w = GetWindow(Window); - if (w) { - w->Index(Color); - w->Reset(); - } -} - -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) -{ - 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 cDvbOsd::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 cDvbOsd::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 cDvbOsd::Width(unsigned char c) -{ - return numWindows ? window[0]->Width(c) : 0; -} - -int cDvbOsd::Width(const char *s) -{ - return numWindows ? window[0]->Width(s) : 0; -} - -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); + 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::Hide(tWindowHandle Window) +void cDvbOsd::ShowWindow(cWindow *Window) { - if (SetWindow(GetWindow(Window))) - Cmd(OSD_Hide, 0); + if (SetWindow(Window)) + Cmd(OSD_MoveWindow, 0, X0() + Window->X0(), Y0() + Window->Y0()); } -void cDvbOsd::Show(tWindowHandle Window) +void cDvbOsd::HideWindow(cWindow *Window, bool Hide) { - if (SetWindow(GetWindow(Window))) - Cmd(OSD_Show, 0); + if (SetWindow(Window)) + Cmd(Hide ? OSD_Hide : OSD_Show, 0); } +void cDvbOsd::MoveWindow(cWindow *Window, int x, int y) +{ + if (SetWindow(Window)) + Cmd(OSD_MoveWindow, 0, X0() + x, Y0() + y); +} + +void cDvbOsd::CloseWindow(cWindow *Window) +{ + if (SetWindow(Window)) + Cmd(OSD_Close); +} 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 -#undef ERR //XXX ncurses defines this - but this clashes with newer system header files -#endif #include -#include -#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 +#include +#include +#include +#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 +#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