diff --git a/HISTORY b/HISTORY index 96b90081..20490559 100644 --- a/HISTORY +++ b/HISTORY @@ -534,7 +534,7 @@ Video Disk Recorder Revision History - No longer getting stuck when a channel doesn't sync while switching with the 'Up' and 'Down' keys. -2001-07-21: Version 0.84 +2001-07-22: Version 0.84 - Fixed video packet scanning to make it recognize the whole range of allowed video packet ids. @@ -555,3 +555,7 @@ Video Disk Recorder Revision History - Increased the frame buffer size to 192KB. - Removed a superfluous VIDEO_FREEZE call in the replay buffer. - Added French language texts (thanks to Jean-Claude Repetto). +- Modified OSD to use 2bpp windows (4 colors) in order to work with less + memory, allow a larger OSD window and be faster. The group separators in the + "Channels" menu had to be given a different color. +- Moved the channel display to the bottom of the screen. diff --git a/dvbapi.c b/dvbapi.c index 237b3e76..fd37773b 100644 --- a/dvbapi.c +++ b/dvbapi.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbapi.c 1.86 2001/07/22 09:34:55 kls Exp $ + * $Id: dvbapi.c 1.87 2001/07/22 12:18:29 kls Exp $ */ #include "dvbapi.h" @@ -1843,25 +1843,6 @@ void cDvbApi::SetColor(eDvbColor colorFg, eDvbColor colorBg) } } } -#else -void cDvbApi::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1, const void *data) -{ - if (fd_osd >= 0) { - osd_cmd_t dc; - dc.cmd = cmd; - dc.color = color; - dc.x0 = x0; - dc.y0 = y0; - dc.x1 = x1; - dc.y1 = y1; - dc.data = (void *)data; - CHECK(ioctl(fd_osd, OSD_SEND_CMD, &dc)); - usleep(10); // XXX Workaround for a driver bug (cInterface::DisplayChannel() displayed texts at wrong places - // XXX and sometimes the OSD was no longer displayed). - // XXX Increase the value if the problem still persists on your particular system. - // TODO Check if this is still necessary with driver versions after 0.6. - } -} #endif void cDvbApi::Open(int w, int h) @@ -1875,16 +1856,7 @@ void cDvbApi::Open(int w, int h) syncok(window, true); #define B2C(b) (((b) * 1000) / 255) #define SETCOLOR(n, r, g, b, o) init_color(n, B2C(r), B2C(g), B2C(b)) -#else - w *= charWidth; - h *= lineHeight; - d *= lineHeight; - int x = (720 - MenuColumns * charWidth) / 2; //TODO PAL vs. NTSC??? - int y = (576 - MenuLines * lineHeight) / 2 + d; - osd = new cDvbOsd(fd_osd, x, y, x + w - 1, y + h - 1, 4); - #define SETCOLOR(n, r, g, b, o) Cmd(OSD_SetColor, n, r, g, b, o) - SETCOLOR(clrTransparent, 0x00, 0x00, 0x00, 0); -#endif + //XXX SETCOLOR(clrBackground, 0x00, 0x00, 0x00, 127); // background 50% gray SETCOLOR(clrBlack, 0x00, 0x00, 0x00, 255); SETCOLOR(clrRed, 0xFC, 0x14, 0x14, 255); @@ -1894,6 +1866,35 @@ void cDvbApi::Open(int w, int h) SETCOLOR(clrCyan, 0x00, 0xFC, 0xFC, 255); SETCOLOR(clrMagenta, 0xB0, 0x00, 0xFC, 255); SETCOLOR(clrWhite, 0xFC, 0xFC, 0xFC, 255); +#else + w *= charWidth; + h *= lineHeight; + d *= lineHeight; + int x = (720 - (MenuColumns - 1) * charWidth) / 2; //TODO PAL vs. NTSC??? + int y = (576 - MenuLines * lineHeight) / 2 + d; + //XXX + osd = new cDvbOsd(fd_osd, x, y); + //XXX TODO this should be transferred to the places where the individual windows are requested (there's too much detailed knowledge here!) + if (d == 0) { //XXX full menu + osd->Create(0, 0, w, lineHeight, 2); + osd->Create(0, lineHeight, w, (MenuLines - 3) * lineHeight, 2, true, clrBackground, clrCyan, clrWhite, clrBlack); + osd->Create(0, (MenuLines - 2) * lineHeight, w, 2 * lineHeight, 4); + } + else if (h / lineHeight == 5) { //XXX channel display + osd->Create(0, 0, w, h, 4); + } + else if (h / lineHeight == 1) { //XXX info display + osd->Create(0, 0, w, h, 4); + } + else { //XXX progress display + /*XXX + osd->Create(0, 0, w, lineHeight, 1); + osd->Create(0, lineHeight, w, lineHeight, 2, false); + osd->Create(0, 2 * lineHeight, w, lineHeight, 1); + XXX*///XXX some pixels are not drawn correctly with lower bpp values + osd->Create(0, 0, w, 3*lineHeight, 4); + } +#endif } void cDvbApi::Close(void) diff --git a/dvbapi.h b/dvbapi.h index 7ed0196f..0285985c 100644 --- a/dvbapi.h +++ b/dvbapi.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbapi.h 1.40 2001/06/24 17:42:19 kls Exp $ + * $Id: dvbapi.h 1.41 2001/07/22 11:48:15 kls Exp $ */ #ifndef __DVBAPI_H @@ -36,8 +36,8 @@ typedef struct CRect { signed short x, y, width, height; }; -#define MenuLines 13 // XXX originally 15, but since driver version 2001-05-25 there is less OSD memory :-( -#define MenuColumns 40 +#define MenuLines 18 +#define MenuColumns 52 const char *IndexToHMSF(int Index, bool WithFrame = false); // Converts the given index to a string, optionally containing the frame number. @@ -159,7 +159,6 @@ private: cDvbOsd *osd; #endif int cols, rows; - void Cmd(OSD_Command cmd, int color = 0, int x0 = 0, int y0 = 0, int x1 = 0, int y1 = 0, const void *data = NULL); public: void Open(int w, int h); void Close(void); diff --git a/dvbosd.c b/dvbosd.c index 0ea90e7e..c05dcb85 100644 --- a/dvbosd.c +++ b/dvbosd.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbosd.c 1.8 2001/05/26 11:49:35 kls Exp $ + * $Id: dvbosd.c 1.9 2001/07/22 11:48:54 kls Exp $ */ #include "dvbosd.h" @@ -14,12 +14,83 @@ #include #include "tools.h" +// --- cPalette -------------------------------------------------------------- + +cPalette::cPalette(int Bpp) +{ + maxColors = 1 << Bpp; + numColors = 0; + full = false; +} + +int cPalette::Index(eDvbColor Color) +{ + 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) +cBitmap::cBitmap(int Width, int Height, int Bpp, bool ClearWithBackground) +:cPalette(Bpp) { width = Width; height = Height; + clearWithBackground = ClearWithBackground; bitmap = NULL; fontType = fontOsd; font = NULL; @@ -27,7 +98,7 @@ cBitmap::cBitmap(int Width, int Height) bitmap = new char[width * height]; if (bitmap) { Clean(); - memset(bitmap, clrTransparent, width * height); + memset(bitmap, 0x00, width * height); SetFont(fontOsd); } else @@ -54,9 +125,38 @@ eDvbFont cBitmap::SetFont(eDvbFont Font) return oldFont; } -bool cBitmap::Dirty(void) +bool cBitmap::Dirty(int &x1, int &y1, int &x2, int &y2) { - return dirtyX2 >= 0; + 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) @@ -67,12 +167,12 @@ void cBitmap::Clean(void) dirtyY2 = -1; } -void cBitmap::SetPixel(int x, int y, eDvbColor Color) +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] != Color) { - bitmap[width * y + x] = Color; + 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; @@ -82,12 +182,19 @@ void cBitmap::SetPixel(int x, int y, eDvbColor Color) } } +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++) - SetPixel(x + ix, y + iy, eDvbColor(Bitmap.bitmap[Bitmap.width * iy + ix])); + SetIndex(x + ix, y + iy, Indexes[Bitmap.bitmap[Bitmap.width * iy + ix]]); } } } @@ -105,6 +212,8 @@ int cBitmap::Width(const char *s) 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++); @@ -113,7 +222,7 @@ void cBitmap::Text(int x, int y, const char *s, eDvbColor ColorFg, eDvbColor Col for (int row = 0; row < h; row++) { cFont::tPixelData PixelData = CharData->lines[row]; for (int col = CharData->width; col-- > 0; ) { - SetPixel(x + col, y + row, (PixelData & 1) ? ColorFg : ColorBg); + SetIndex(x + col, y + row, (PixelData & 1) ? fg : bg); PixelData >>= 1; } } @@ -125,33 +234,103 @@ void cBitmap::Text(int x, int y, const char *s, eDvbColor ColorFg, eDvbColor Col 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++) - SetPixel(x, y, Color); + SetIndex(x, y, c); } } void cBitmap::Clear(void) { - Fill(0, 0, width - 1, height - 1, clrBackground); + 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 x0, y0; + bool shown; +public: + cWindow(int x, int y, int w, int h, int Bpp, bool ClearWithBackground = true); + int X0(void) { return x0; } + int Y0(void) { return y0; } + bool Shown(void) { bool s = shown; shown = true; return s; } + bool Contains(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 x, int y, int w, int h, int Bpp, bool ClearWithBackground) +:cBitmap(w, h, Bpp, ClearWithBackground) +{ + x0 = x; + y0 = y; + shown = false; +} + +bool cWindow::Contains(int x, int y) +{ + x -= x0; + y -= y0; + return x >= 0 && y >= 0 && x < width && y < height; +} + +void cWindow::Fill(int x1, int y1, int x2, int y2, eDvbColor Color) +{ + cBitmap::Fill(x1 - x0, y1 - y0, x2 - x0, y2 - y0, Color); +} + +void cWindow::SetBitmap(int x, int y, const cBitmap &Bitmap) +{ + cBitmap::SetBitmap(x - x0, y - y0, Bitmap); +} + +void cWindow::Text(int x, int y, const char *s, eDvbColor ColorFg, eDvbColor ColorBg) +{ + cBitmap::Text(x - x0, y - y0, s, ColorFg, ColorBg); +} + +const char *cWindow::Data(int x, int y) +{ + return cBitmap::Data(x, y); } // --- cDvbOsd --------------------------------------------------------------- -cDvbOsd::cDvbOsd(int VideoDev, int x1, int y1, int x2, int y2, int Bpp) -:cBitmap(x2 - x1 + 1, y2 - y1 + 1) +cDvbOsd::cDvbOsd(int VideoDev, int x, int y, int w, int h, int Bpp) { videoDev = VideoDev; - if (videoDev >= 0) - Cmd(OSD_Open, Bpp, x1, y1, x2, y2); + numWindows = 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); } cDvbOsd::~cDvbOsd() { - if (videoDev >= 0) - Cmd(OSD_Close); + if (videoDev >= 0) { + while (numWindows > 0) { + Cmd(OSD_SetWindow, 0, numWindows--); + Cmd(OSD_Close); + delete window[numWindows]; + } + } } void cDvbOsd::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1, const void *data) @@ -178,32 +357,111 @@ void cDvbOsd::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1, co } } -void cDvbOsd::Flush(void) +bool cDvbOsd::Create(int x, int y, int w, int h, int Bpp, bool ClearWithBackground, eDvbColor Color0, eDvbColor Color1, eDvbColor Color2, eDvbColor Color3) { - if (Dirty()) { - //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--; + /* TODO XXX + - check that no two windows overlap + */ + 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); } - 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--; + cWindow *win = new cWindow(x, y, w, h, Bpp, ClearWithBackground); + if (Color0 != clrTransparent) { + win->Index(Color0); + win->Index(Color1); + win->Index(Color2); + win->Index(Color3); + win->Reset(); } - 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--; - } - Cmd(OSD_SetBlock, width, dirtyX1, dirtyY1, dirtyX2, dirtyY2, &bitmap[dirtyY1 * width + dirtyX1]); - Clean(); + window[numWindows++] = win; + Cmd(OSD_SetWindow, 0, numWindows); + Cmd(OSD_Open, Bpp, x0 + x, y0 + y, x0 + x + w - 1, y0 + y + h - 1, (void *)1); // initially hidden! + } + else + esyslog(LOG_ERR, "ERROR: illegal OSD parameters"); } + else + esyslog(LOG_ERR, "ERROR: too many OSD windows"); + return false; +} + +cWindow *cDvbOsd::GetWindow(int x, int y) +{ + for (int i = 0; i < numWindows; i++) { + if (window[i]->Contains(x, y)) + return window[i]; + } + 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)) { + Cmd(OSD_SetWindow, 0, i + 1); + 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()) { + Cmd(OSD_SetWindow, 0, i + 1); + Cmd(OSD_MoveWindow, 0, x0 + window[i]->X0(), y0 + window[i]->Y0()); + } + } +} + +void cDvbOsd::Clear(void) +{ + for (int i = 0; i < numWindows; i++) + window[i]->Clear(); +} + +void cDvbOsd::Fill(int x1, int y1, int x2, int y2, eDvbColor Color) +{ + cWindow *w = GetWindow(x1, y1); + if (w) + w->Fill(x1, y1, x2, y2, Color); +} + +void cDvbOsd::SetBitmap(int x, int y, const cBitmap &Bitmap) +{ + cWindow *w = GetWindow(x, y); + 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) +{ + cWindow *w = GetWindow(x, y); + if (w) + w->Text(x, y, s, ColorFg, ColorBg); } diff --git a/dvbosd.h b/dvbosd.h index 88320fa4..1418d60f 100644 --- a/dvbosd.h +++ b/dvbosd.h @@ -4,17 +4,12 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbosd.h 1.6 2001/05/01 14:41:42 kls Exp $ + * $Id: dvbosd.h 1.7 2001/07/22 11:49:35 kls Exp $ */ #ifndef __DVBOSD_H #define __DVBOSD_H -// FIXME: these should be defined in ../DVB/driver/dvb.h!!! -typedef unsigned int __u32; -typedef unsigned short __u16; -typedef unsigned char __u8; - #if defined(DEBUG_OSD) || defined(REMOTE_KBD) #include #endif @@ -22,57 +17,96 @@ typedef unsigned char __u8; #include #include "font.h" +#define MAXNUMCOLORS 16 + enum eDvbColor { #ifndef DEBUG_OSD - clrTransparent, + clrTransparent = 0x00000000, #endif - clrBackground, + clrBackground = 0x7F000000, // 50% gray #ifdef DEBUG_OSD clrTransparent = clrBackground, clrBlack = clrBackground, #else - clrBlack, + clrBlack = 0xFF000000, #endif - clrRed, - clrGreen, - clrYellow, - clrBlue, - clrMagenta, - clrCyan, - clrWhite, + clrRed = 0xFF1414FC, + clrGreen = 0xFF24FC24, + clrYellow = 0xFF24C0FC, + clrMagenta = 0xFFFC00B0, + clrBlue = 0xFFFC0000, + clrCyan = 0xFFFCFC00, + clrWhite = 0xFFFCFCFC, }; -class cBitmap { +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; - char *bitmap; int dirtyX1, dirtyY1, dirtyX2, dirtyY2; - void Clean(void); public: - cBitmap(int Width, int Height); + cBitmap(int Width, int Height, int Bpp, bool ClearWithBackground = true); virtual ~cBitmap(); eDvbFont SetFont(eDvbFont Font); - bool Dirty(void); + 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); }; -class cDvbOsd : public cBitmap { +#define MAXNUMWINDOWS 7 // OSD windows are counted 1...7 + +class cWindow; + +class cDvbOsd { private: int videoDev; + int numWindows; + int x0, y0; + cWindow *window[MAXNUMWINDOWS]; 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); public: - cDvbOsd(int VideoDev, int x1, int y1, int x2, int y2, int Bpp); + cDvbOsd(int VideoDev, int x, int y, int w = -1, int h = -1, int Bpp = -1); ~cDvbOsd(); + bool Create(int x, int y, int w, int h, int Bpp, bool ClearWithBackground = true, eDvbColor Color0 = clrTransparent, eDvbColor Color1 = clrTransparent, eDvbColor Color2 = clrTransparent, eDvbColor Color3 = clrTransparent); void Flush(void); + void Clear(void); + void Fill(int x1, int y1, int x2, int y2, eDvbColor Color); + void SetBitmap(int x, int y, const cBitmap &Bitmap); + int Width(unsigned char c); + int Width(const char *s); + eDvbFont SetFont(eDvbFont Font); + void Text(int x, int y, const char *s, eDvbColor ColorFg = clrWhite, eDvbColor ColorBg = clrBackground); }; #endif //__DVBOSD_H diff --git a/interface.c b/interface.c index c8d1fb13..55129341 100644 --- a/interface.c +++ b/interface.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: interface.c 1.36 2001/06/02 09:05:54 kls Exp $ + * $Id: interface.c 1.37 2001/07/22 12:26:28 kls Exp $ */ #include "interface.h" @@ -281,14 +281,15 @@ void cInterface::Title(const char *s) void cInterface::Status(const char *s, eDvbColor FgColor, eDvbColor BgColor) { - ClearEol(0, -2, s ? BgColor : clrBackground); + int Line = (abs(height) == 1) ? 0 : -2; + ClearEol(0, Line, s ? BgColor : clrBackground); if (s) - Write(0, -2, s, FgColor, BgColor); + Write(0, Line, s, FgColor, BgColor); } void cInterface::Info(const char *s) { - Open(); + Open(MenuColumns, -1); isyslog(LOG_INFO, "info: %s", s); Status(s, clrWhite, clrGreen); Wait(); @@ -298,7 +299,7 @@ void cInterface::Info(const char *s) void cInterface::Error(const char *s) { - Open(); + Open(MenuColumns, -1); esyslog(LOG_ERR, "ERROR: %s", s); Status(s, clrWhite, clrRed); Wait(); diff --git a/menu.c b/menu.c index 189c9279..6be8c452 100644 --- a/menu.c +++ b/menu.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.c 1.77 2001/07/12 14:56:18 kls Exp $ + * $Id: menu.c 1.78 2001/07/22 12:27:51 kls Exp $ */ #include "menu.h" @@ -585,7 +585,7 @@ cMenuChannelItem::cMenuChannelItem(int Index, cChannel *Channel) index = Index; channel = Channel; if (channel->groupSep) - SetColor(clrWhite, clrBlue); + SetColor(clrWhite, clrCyan); Set(); } @@ -1802,7 +1802,7 @@ cDisplayChannel::cDisplayChannel(int Number, bool Switched, bool Group) lines = 0; oldNumber = number = 0; cChannel *channel = Group ? Channels.Get(Number) : Channels.GetByNumber(Number); - Interface->Open(MenuColumns, 5); + Interface->Open(MenuColumns, -5); if (channel) { DisplayChannel(channel); DisplayInfo(); @@ -1816,7 +1816,7 @@ cDisplayChannel::cDisplayChannel(eKeys FirstKey) oldNumber = cDvbApi::CurrentChannel(); number = 0; lastTime = time_ms(); - Interface->Open(MenuColumns, 5); + Interface->Open(MenuColumns, -5); ProcessKey(FirstKey); } @@ -1843,7 +1843,6 @@ void cDisplayChannel::DisplayChannel(const cChannel *Channel) struct tm *now = localtime(&t); snprintf(buffer, BufSize, "%02d:%02d", now->tm_hour, now->tm_min); Interface->Write(-5, 0, buffer); - Interface->Flush(); } void cDisplayChannel::DisplayInfo(void) @@ -2100,7 +2099,7 @@ public: }; cProgressBar::cProgressBar(int Width, int Height, int Current, int Total, const cMarks &Marks) -:cBitmap(Width, Height) +:cBitmap(Width, Height, 2) { total = Total; if (total > 0) {