diff options
| author | Klaus Schmidinger <vdr@tvdr.de> | 2002-05-10 14:55:53 +0200 | 
|---|---|---|
| committer | Klaus Schmidinger <vdr@tvdr.de> | 2002-05-10 14:55:53 +0200 | 
| commit | 37f89dca4967856b0b780fdfa68b30296968be61 (patch) | |
| tree | 3040e1c023d83d1a5da1991dd74baf3675af4802 | |
| parent | b527b2770868bccde05ad47393951fde5d51f79a (diff) | |
| download | vdr-37f89dca4967856b0b780fdfa68b30296968be61.tar.gz vdr-37f89dca4967856b0b780fdfa68b30296968be61.tar.bz2 | |
Separated the actual DVB hardware OSD implementation from the abstract OSD interface
| -rw-r--r-- | HISTORY | 7 | ||||
| -rw-r--r-- | Makefile | 4 | ||||
| -rw-r--r-- | config.h | 4 | ||||
| -rw-r--r-- | dvbosd.c | 545 | ||||
| -rw-r--r-- | dvbosd.h | 171 | ||||
| -rw-r--r-- | osdbase.c | 482 | ||||
| -rw-r--r-- | osdbase.h | 211 | 
7 files changed, 763 insertions, 661 deletions
| @@ -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. @@ -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 @@ -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 @@ -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); -} - @@ -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 | 
