Separated the actual DVB hardware OSD implementation from the abstract OSD interface

This commit is contained in:
Klaus Schmidinger 2002-05-10 14:55:53 +02:00
parent b527b27708
commit 37f89dca49
7 changed files with 767 additions and 665 deletions

View File

@ -1254,3 +1254,10 @@ Video Disk Recorder Revision History
and '-P' used to load plugins. This first step implements the complete "outer" 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. 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. - 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.

View File

@ -4,7 +4,7 @@
# See the main source file 'vdr.c' for copyright information and # See the main source file 'vdr.c' for copyright information and
# how to reach the author. # how to reach the author.
# #
# $Id: 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: .DELETE_ON_ERROR:
@ -22,7 +22,7 @@ INCLUDES = -I$(DVBDIR)/ost/include
DTVLIB = $(DTVDIR)/libdtv.a DTVLIB = $(DTVDIR)/libdtv.a
OBJS = config.o dvbapi.o dvbosd.o eit.o font.o i18n.o interface.o menu.o\ 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 svdrp.o thread.o tools.o vdr.o videodir.o
OSDFONT = -adobe-helvetica-medium-r-normal--23-*-100-100-p-*-iso8859-1 OSDFONT = -adobe-helvetica-medium-r-normal--23-*-100-100-p-*-iso8859-1

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: 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 #ifndef __CONFIG_H
@ -19,7 +19,7 @@
#include "eit.h" #include "eit.h"
#include "tools.h" #include "tools.h"
#define VDRVERSION "1.1.0" #define VDRVERSION "1.1.1"
#define MAXPRIORITY 99 #define MAXPRIORITY 99
#define MAXLIFETIME 99 #define MAXLIFETIME 99

553
dvbosd.c
View File

@ -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 * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: dvbosd.c 1.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 "dvbosd.h"
#include <signal.h> #include <signal.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/unistd.h> #include <sys/unistd.h>
#include "tools.h" #include "tools.h"
// --- cPalette -------------------------------------------------------------- cDvbOsd::cDvbOsd(int VideoDev, int x, int y)
:cOsd(x, y)
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)
{ {
videoDev = VideoDev; videoDev = VideoDev;
numWindows = 0; if (videoDev < 0)
x0 = x;
y0 = y;
if (videoDev >= 0) {
if (w > 0 && h > 0)
Create(0, 0, w, h, Bpp);
}
else
esyslog(LOG_ERR, "ERROR: illegal video device handle (%d)!", videoDev); esyslog(LOG_ERR, "ERROR: illegal video device handle (%d)!", videoDev);
} }
cDvbOsd::~cDvbOsd() cDvbOsd::~cDvbOsd()
{ {
if (videoDev >= 0) { for (int i = 0; i < NumWindows(); i++)
for (int i = 0; i < numWindows; i++) { CloseWindow(GetWindowNr(i));
SetWindow(window[i]);
Cmd(OSD_Close);
delete window[i];
}
numWindows = 0;
}
} }
bool cDvbOsd::SetWindow(cWindow *Window) bool cDvbOsd::SetWindow(cWindow *Window)
{ {
// Window handles are counted 0...(MAXNUMWINDOWS - 1), but the actual window if (Window) {
// numbers in the driver are used from 1...MAXNUMWINDOWS. // Window handles are counted 0...(MAXNUMWINDOWS - 1), but the actual window
int Handle = Window->Handle(); // numbers in the driver are used from 1...MAXNUMWINDOWS.
if (0 <= Handle && Handle < MAXNUMWINDOWS) { int Handle = Window->Handle();
Cmd(OSD_SetWindow, 0, Handle + 1); if (0 <= Handle && Handle < MAXNUMWINDOWS) {
return true; 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 false;
return -1;
} }
void cDvbOsd::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1, const void *data) 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 (SetWindow(Window)) {
if (x >= 0 && y >= 0 && w > 0 && h > 0 && (Bpp == 1 || Bpp == 2 || Bpp == 4 || Bpp == 8)) { 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!
if ((w & 0x03) != 0) { return true;
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 return false;
esyslog(LOG_ERR, "ERROR: too many OSD windows");
return -1;
} }
void cDvbOsd::AddColor(eDvbColor Color, tWindowHandle Window) void cDvbOsd::CommitWindow(cWindow *Window)
{ {
cWindow *w = GetWindow(Window); if (SetWindow(Window)) {
if (w) { int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
w->Index(Color); if (Window->Dirty(x1, y1, x2, y2)) {
w->Reset(); // commit colors:
} int FirstColor = 0, LastColor = 0;
} const eDvbColor *pal;
while ((pal = Window->Colors(FirstColor, LastColor)) != NULL)
cWindow *cDvbOsd::GetWindow(int x, int y) Cmd(OSD_SetPalette, FirstColor, LastColor, 0, 0, 0, pal);
{ // commit modified data:
for (int i = 0; i < numWindows; i++) { Cmd(OSD_SetBlock, Window->Width(), x1, y1, x2, y2, Window->Data(x1, y1));
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);
} }
} }
} }
void cDvbOsd::Hide(tWindowHandle Window) void cDvbOsd::ShowWindow(cWindow *Window)
{ {
if (SetWindow(GetWindow(Window))) if (SetWindow(Window))
Cmd(OSD_Hide, 0); 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))) if (SetWindow(Window))
Cmd(OSD_Show, 0); 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);
}

171
dvbosd.h
View File

@ -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 * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: dvbosd.h 1.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 #ifndef __DVBOSD_H
#define __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 <ost/osd.h>
#include <stdio.h> #include "osdbase.h"
#include "font.h"
#define MAXNUMCOLORS 16 class cDvbOsd : public cOsd {
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 {
private: private:
int videoDev; int videoDev;
int numWindows;
int x0, y0;
cWindow *window[MAXNUMWINDOWS];
bool SetWindow(cWindow *Window); 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); 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); protected:
cWindow *GetWindow(tWindowHandle Window); 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: public:
cDvbOsd(int VideoDev, int x, int y, int w = -1, int h = -1, int Bpp = -1); cDvbOsd(int VideoDev, int x, int y);
// Initializes the OSD on the given VideoDev, starting at screen coordinates virtual ~cDvbOsd();
// (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.
}; };
#endif //__DVBOSD_H #endif //__DVBOSD_H

482
osdbase.c Normal file
View File

@ -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);
}

211
osdbase.h Normal file
View File

@ -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