From bdccbbe93e9729944787d3158bee7a755d3bf286 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sat, 18 May 2002 14:03:22 +0200 Subject: [PATCH] Completely moved OSD handling out of the cDvbApi class, into the new cOsd --- HISTORY | 1 + dvbapi.c | 221 +------------------------------------------------ dvbapi.h | 47 ++--------- dvbosd.c | 14 ++-- dvbosd.h | 6 +- interface.c | 31 +++---- interface.h | 4 +- menu.c | 10 +-- menuitems.c | 12 +-- osd.c | 232 +++++++++++++++++++++++++++++++++++++++++++++++++++- osd.h | 39 ++++++++- remote.c | 6 +- vdr.c | 12 ++- 13 files changed, 332 insertions(+), 303 deletions(-) diff --git a/HISTORY b/HISTORY index 01ab2984..1a256773 100644 --- a/HISTORY +++ b/HISTORY @@ -1309,3 +1309,4 @@ Video Disk Recorder Revision History - Added an error message if the directory specified in the '-L' option can't be accessed (suggested by Stefan Huelswitt). - Rearranged OSD class names to make 'cOsd' available for the main OSD interface. +- Completely moved OSD handling out of the cDvbApi class, into the new cOsd. diff --git a/dvbapi.c b/dvbapi.c index 7475a0b6..bb2d13aa 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.176 2002/05/18 09:21:39 kls Exp $ + * $Id: dvbapi.c 1.177 2002/05/18 14:03:17 kls Exp $ */ #include "dvbapi.h" @@ -1759,24 +1759,7 @@ cDvbApi::cDvbApi(int n) } else esyslog("ERROR: can't open video device %d", n); - cols = rows = 0; -#if defined(DEBUG_OSD) || defined(REMOTE_KBD) - initscr(); - keypad(stdscr, true); - nonl(); - cbreak(); - noecho(); - timeout(10); -#endif -#if defined(DEBUG_OSD) - memset(&colorPairs, 0, sizeof(colorPairs)); - start_color(); - leaveok(stdscr, true); - window = NULL; -#else - osd = NULL; -#endif currentChannel = 1; mute = false; volume = Setup.CurrentVolume; @@ -1785,15 +1768,11 @@ cDvbApi::cDvbApi(int n) cDvbApi::~cDvbApi() { delete siProcessor; - Close(); StopReplay(); StopRecord(); StopTransfer(); // We're not explicitly closing any device files here, since this sometimes // caused segfaults. Besides, the program is about to terminate anyway... -#if defined(DEBUG_OSD) || defined(REMOTE_KBD) - endwin(); -#endif } void cDvbApi::SetUseDvbApi(int n) @@ -1923,7 +1902,7 @@ bool cDvbApi::Probe(const char *FileName) return false; } -bool cDvbApi::Init(void) +bool cDvbApi::Initialize(void) { NumDvbApis = 0; for (int i = 0; i < MAXDVBAPI; i++) { @@ -1943,7 +1922,7 @@ bool cDvbApi::Init(void) return NumDvbApis > 0; } -void cDvbApi::Cleanup(void) +void cDvbApi::Shutdown(void) { for (int i = 0; i < NumDvbApis; i++) { delete dvbApi[i]; @@ -2045,200 +2024,6 @@ bool cDvbApi::GrabImage(const char *FileName, bool Jpeg, int Quality, int SizeX, return false; } -#ifdef DEBUG_OSD -void cDvbApi::SetColor(eDvbColor colorFg, eDvbColor colorBg) -{ - int color = (colorBg << 16) | colorFg | 0x80000000; - for (int i = 0; i < MaxColorPairs; i++) { - if (!colorPairs[i]) { - colorPairs[i] = color; - init_pair(i + 1, colorFg, colorBg); - wattrset(window, COLOR_PAIR(i + 1)); - break; - } - else if (color == colorPairs[i]) { - wattrset(window, COLOR_PAIR(i + 1)); - break; - } - } -} -#endif - -void cDvbApi::Open(int w, int h) -{ - int d = (h < 0) ? Setup.OSDheight + h : 0; - h = abs(h); - cols = w; - rows = h; -#ifdef DEBUG_OSD - window = subwin(stdscr, h, w, d, (Setup.OSDwidth - w) / 2); - 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)) - //XXX - SETCOLOR(clrBackground, 0x00, 0x00, 0x00, 127); // background 50% gray - SETCOLOR(clrBlack, 0x00, 0x00, 0x00, 255); - SETCOLOR(clrRed, 0xFC, 0x14, 0x14, 255); - SETCOLOR(clrGreen, 0x24, 0xFC, 0x24, 255); - SETCOLOR(clrYellow, 0xFC, 0xC0, 0x24, 255); - SETCOLOR(clrBlue, 0x00, 0x00, 0xFC, 255); - 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 - w + charWidth) / 2; //TODO PAL vs. NTSC??? - int y = (576 - Setup.OSDheight * 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 (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 if (d == 0) { //XXX full menu - osd->Create(0, 0, w, lineHeight, 2); - osd->Create(0, lineHeight, w, (Setup.OSDheight - 3) * lineHeight, 2); - osd->AddColor(clrBackground); - osd->AddColor(clrCyan); - osd->AddColor(clrWhite); - osd->AddColor(clrBlack); - osd->Create(0, (Setup.OSDheight - 2) * lineHeight, w, 2 * lineHeight, 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) -{ -#ifdef DEBUG_OSD - if (window) { - delwin(window); - window = 0; - } -#else - delete osd; - osd = NULL; -#endif -} - -void cDvbApi::Clear(void) -{ -#ifdef DEBUG_OSD - SetColor(clrBackground, clrBackground); - Fill(0, 0, cols, rows, clrBackground); -#else - osd->Clear(); -#endif -} - -void cDvbApi::Fill(int x, int y, int w, int h, eDvbColor color) -{ - if (x < 0) x = cols + x; - if (y < 0) y = rows + y; -#ifdef DEBUG_OSD - SetColor(color, color); - for (int r = 0; r < h; r++) { - wmove(window, y + r, x); // ncurses wants 'y' before 'x'! - whline(window, ' ', w); - } - wsyncup(window); // shouldn't be necessary because of 'syncok()', but w/o it doesn't work -#else - osd->Fill(x * charWidth, y * lineHeight, (x + w) * charWidth - 1, (y + h) * lineHeight - 1, color); -#endif -} - -void cDvbApi::SetBitmap(int x, int y, const cBitmap &Bitmap) -{ -#ifndef DEBUG_OSD - osd->SetBitmap(x, y, Bitmap); -#endif -} - -void cDvbApi::ClrEol(int x, int y, eDvbColor color) -{ - Fill(x, y, cols - x, 1, color); -} - -int cDvbApi::CellWidth(void) -{ -#ifdef DEBUG_OSD - return 1; -#else - return charWidth; -#endif -} - -int cDvbApi::LineHeight(void) -{ -#ifdef DEBUG_OSD - return 1; -#else - return lineHeight; -#endif -} - -int cDvbApi::Width(unsigned char c) -{ -#ifdef DEBUG_OSD - return 1; -#else - return osd->Width(c); -#endif -} - -int cDvbApi::WidthInCells(const char *s) -{ -#ifdef DEBUG_OSD - return strlen(s); -#else - return (osd->Width(s) + charWidth - 1) / charWidth; -#endif -} - -eDvbFont cDvbApi::SetFont(eDvbFont Font) -{ -#ifdef DEBUG_OSD - return Font; -#else - return osd->SetFont(Font); -#endif -} - -void cDvbApi::Text(int x, int y, const char *s, eDvbColor colorFg, eDvbColor colorBg) -{ - if (x < 0) x = cols + x; - if (y < 0) y = rows + y; -#ifdef DEBUG_OSD - SetColor(colorFg, colorBg); - wmove(window, y, x); // ncurses wants 'y' before 'x'! - waddnstr(window, s, cols - x); -#else - osd->Text(x * charWidth, y * lineHeight, s, colorFg, colorBg); -#endif -} - -void cDvbApi::Flush(void) -{ -#ifdef DEBUG_OSD - refresh(); -#else - if (osd) - osd->Flush(); -#endif -} - int cDvbApi::Priority(void) { return (this == PrimaryDvbApi && !Recording()) ? Setup.PrimaryLimit - 1 : priority; diff --git a/dvbapi.h b/dvbapi.h index 7e638786..4eb29bcb 100644 --- a/dvbapi.h +++ b/dvbapi.h @@ -4,16 +4,12 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbapi.h 1.69 2002/04/21 09:49:22 kls Exp $ + * $Id: dvbapi.h 1.70 2002/05/18 14:03:12 kls Exp $ */ #ifndef __DVBAPI_H #define __DVBAPI_H -#if defined(DEBUG_OSD) || defined(REMOTE_KBD) -#include -#undef ERR //XXX ncurses defines this - but this clashes with newer system header files -#endif #include // FIXME: this is apparently necessary for the ost/... header files // FIXME: shouldn't every header file include ALL the other header // FIXME: files it depends on? The sequence in which header files @@ -25,10 +21,7 @@ #include #include #include -#include #include - -#include "dvbosd.h" #include "eit.h" #include "thread.h" @@ -76,6 +69,7 @@ public: }; class cDvbApi { + friend class cOsd; friend class cRecordBuffer; friend class cReplayBuffer; friend class cTransferBuffer; @@ -83,6 +77,7 @@ private: FrontendType frontendType; int fd_osd, fd_frontend, fd_sec, fd_dvr, fd_audio, fd_video, fd_demuxa1, fd_demuxa2, fd_demuxd1, fd_demuxd2, fd_demuxv, fd_demuxt; int vPid, aPid1, aPid2, dPid1, dPid2; + int OsdDeviceHandle(void) { return fd_osd; } bool SetPid(int fd, dmxPesType_t PesType, int Pid, dmxOutput_t Output); bool SetVpid(int Vpid, dmxOutput_t Output) { return SetPid(fd_demuxv, DMX_PES_VIDEO, Vpid, Output); } bool SetApid1(int Apid, dmxOutput_t Output) { return SetPid(fd_demuxa1, DMX_PES_AUDIO, Apid, Output); } @@ -109,7 +104,7 @@ public: static cDvbApi *PrimaryDvbApi; static void SetUseDvbApi(int n); // Sets the 'useDvbApi' flag of the given DVB device. - // If this function is not called before Init(), all DVB devices + // If this function is not called before Initialize(), all DVB devices // will be used. static bool SetPrimaryDvbApi(int n); // Sets the primary DVB device to 'n' (which must be in the range @@ -137,10 +132,10 @@ public: // in caCaps is returned. static bool Probe(const char *FileName); // Probes for existing DVB devices. - static bool Init(void); + static bool Initialize(void); // Initializes the DVB API. // Must be called before accessing any DVB functions. - static void Cleanup(void); + static void Shutdown(void); // Closes down all DVB devices. // Must be called at the end of the program. @@ -153,36 +148,6 @@ public: bool GrabImage(const char *FileName, bool Jpeg = true, int Quality = -1, int SizeX = -1, int SizeY = -1); - // On Screen Display facilities - -private: - enum { charWidth = 12, // average character width - lineHeight = 27 // smallest text height - }; -#ifdef DEBUG_OSD - WINDOW *window; - enum { MaxColorPairs = 16 }; - int colorPairs[MaxColorPairs]; - void SetColor(eDvbColor colorFg, eDvbColor colorBg = clrBackground); -#else - cDvbOsd *osd; -#endif - int cols, rows; -public: - void Open(int w, int h); - void Close(void); - void Clear(void); - void Fill(int x, int y, int w, int h, eDvbColor color = clrBackground); - void SetBitmap(int x, int y, const cBitmap &Bitmap); - void ClrEol(int x, int y, eDvbColor color = clrBackground); - int CellWidth(void); - int LineHeight(void); - int Width(unsigned char c); - int WidthInCells(const char *s); - eDvbFont SetFont(eDvbFont Font); - void Text(int x, int y, const char *s, eDvbColor colorFg = clrWhite, eDvbColor colorBg = clrBackground); - void Flush(void); - // Video format facilities: void SetVideoFormat(videoFormat_t Format); diff --git a/dvbosd.c b/dvbosd.c index a0b41d58..ad51966f 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.16 2002/05/18 12:39:39 kls Exp $ + * $Id: dvbosd.c 1.17 2002/05/18 13:39:02 kls Exp $ */ #include "dvbosd.h" @@ -13,12 +13,12 @@ #include #include "tools.h" -cDvbOsd::cDvbOsd(int VideoDev, int x, int y) +cDvbOsd::cDvbOsd(int OsdDev, int x, int y) :cOsdBase(x, y) { - videoDev = VideoDev; - if (videoDev < 0) - esyslog("ERROR: illegal video device handle (%d)!", videoDev); + osdDev = OsdDev; + if (osdDev < 0) + esyslog("ERROR: illegal OSD device handle (%d)!", osdDev); } cDvbOsd::~cDvbOsd() @@ -44,7 +44,7 @@ bool cDvbOsd::SetWindow(cWindow *Window) void cDvbOsd::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1, const void *data) { - if (videoDev >= 0) { + if (osdDev >= 0) { osd_cmd_t dc; dc.cmd = cmd; dc.color = color; @@ -58,7 +58,7 @@ void cDvbOsd::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1, co sigfillset(&set); sigdelset(&set, SIGALRM); sigprocmask(SIG_BLOCK, &set, &oldset); - ioctl(videoDev, OSD_SEND_CMD, &dc); + ioctl(osdDev, OSD_SEND_CMD, &dc); if (cmd == OSD_SetBlock) // XXX this is the only command that takes longer usleep(5000); // XXX Workaround for a driver bug (cInterface::DisplayChannel() displayed texts at wrong places // XXX and sometimes the OSD was no longer displayed). diff --git a/dvbosd.h b/dvbosd.h index acecd0ee..0bc6079f 100644 --- a/dvbosd.h +++ b/dvbosd.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbosd.h 1.12 2002/05/18 12:39:31 kls Exp $ + * $Id: dvbosd.h 1.13 2002/05/18 13:38:09 kls Exp $ */ #ifndef __DVBOSD_H @@ -15,7 +15,7 @@ class cDvbOsd : public cOsdBase { private: - int videoDev; + int osdDev; 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); protected: @@ -26,7 +26,7 @@ protected: virtual void MoveWindow(cWindow *Window, int x, int y); virtual void CloseWindow(cWindow *Window); public: - cDvbOsd(int VideoDev, int x, int y); + cDvbOsd(int OsdDev, int x, int y); virtual ~cDvbOsd(); }; diff --git a/interface.c b/interface.c index 0731f0d4..3bd48434 100644 --- a/interface.c +++ b/interface.c @@ -4,13 +4,14 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: interface.c 1.48 2002/05/13 16:30:22 kls Exp $ + * $Id: interface.c 1.49 2002/05/18 13:08:20 kls Exp $ */ #include "interface.h" #include #include #include "i18n.h" +#include "osd.h" cInterface *Interface = NULL; @@ -50,7 +51,7 @@ void cInterface::Open(int NumCols, int NumLines) NumCols = Setup.OSDwidth; if (NumLines == 0) NumLines = Setup.OSDheight; - cDvbApi::PrimaryDvbApi->Open(width = NumCols, height = NumLines); + cOsd::Open(width = NumCols, height = NumLines); } } @@ -59,7 +60,7 @@ void cInterface::Close(void) if (open == 1) Clear(); if (!--open) { - cDvbApi::PrimaryDvbApi->Close(); + cOsd::Close(); width = height = 0; } } @@ -125,31 +126,31 @@ eKeys cInterface::Wait(int Seconds, bool KeepChar) void cInterface::Clear(void) { if (open) - cDvbApi::PrimaryDvbApi->Clear(); + cOsd::Clear(); } void cInterface::ClearEol(int x, int y, eDvbColor Color) { if (open) - cDvbApi::PrimaryDvbApi->ClrEol(x, y, Color); + cOsd::ClrEol(x, y, Color); } void cInterface::Fill(int x, int y, int w, int h, eDvbColor Color) { if (open) - cDvbApi::PrimaryDvbApi->Fill(x, y, w, h, Color); + cOsd::Fill(x, y, w, h, Color); } void cInterface::SetBitmap(int x, int y, const cBitmap &Bitmap) { if (open) - cDvbApi::PrimaryDvbApi->SetBitmap(x, y, Bitmap); + cOsd::SetBitmap(x, y, Bitmap); } void cInterface::Flush(void) { if (open) - cDvbApi::PrimaryDvbApi->Flush(); + cOsd::Flush(); } void cInterface::SetCols(int *c) @@ -163,7 +164,7 @@ void cInterface::SetCols(int *c) eDvbFont cInterface::SetFont(eDvbFont Font) { - return cDvbApi::PrimaryDvbApi->SetFont(Font); + return cOsd::SetFont(Font); } char *cInterface::WrapText(const char *Text, int Width, int *Height) @@ -183,7 +184,7 @@ char *cInterface::WrapText(const char *Text, int Width, int *Height) char *Delim = NULL; int w = 0; - Width *= cDvbApi::PrimaryDvbApi->CellWidth(); + Width *= cOsd::CellWidth(); while (*t && t[strlen(t) - 1] == '\n') t[strlen(t) - 1] = 0; // skips trailing newlines @@ -198,7 +199,7 @@ char *cInterface::WrapText(const char *Text, int Width, int *Height) } else if (isspace(*p)) Blank = p; - int cw = cDvbApi::PrimaryDvbApi->Width(*p); + int cw = cOsd::Width(*p); if (w + cw > Width) { if (Blank) { *Blank = '\n'; @@ -237,7 +238,7 @@ char *cInterface::WrapText(const char *Text, int Width, int *Height) void cInterface::Write(int x, int y, const char *s, eDvbColor FgColor, eDvbColor BgColor) { if (open) - cDvbApi::PrimaryDvbApi->Text(x, y, s, FgColor, BgColor); + cOsd::Text(x, y, s, FgColor, BgColor); } void cInterface::WriteText(int x, int y, const char *s, eDvbColor FgColor, eDvbColor BgColor) @@ -278,7 +279,7 @@ void cInterface::Title(const char *s) strn0cpy(buffer, s, n + 1); Write(1, 0, buffer, clrBlack, clrCyan); t++; - Write(-(cDvbApi::PrimaryDvbApi->WidthInCells(t) + 1), 0, t, clrBlack, clrCyan); + Write(-(cOsd::WidthInCells(t) + 1), 0, t, clrBlack, clrCyan); } else { int x = (Width() - strlen(s)) / 2; @@ -337,12 +338,12 @@ void cInterface::HelpButton(int Index, const char *Text, eDvbColor FgColor, eDvb { if (open) { const int w = Width() / 4; - cDvbApi::PrimaryDvbApi->Fill(Index * w, -1, w, 1, Text ? BgColor : clrBackground); + cOsd::Fill(Index * w, -1, w, 1, Text ? BgColor : clrBackground); if (Text) { int l = (w - int(strlen(Text))) / 2; if (l < 0) l = 0; - cDvbApi::PrimaryDvbApi->Text(Index * w + l, -1, Text, FgColor, BgColor); + cOsd::Text(Index * w + l, -1, Text, FgColor, BgColor); } } } diff --git a/interface.h b/interface.h index 914a3834..240db631 100644 --- a/interface.h +++ b/interface.h @@ -4,14 +4,14 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: interface.h 1.25 2002/04/19 13:17:15 kls Exp $ + * $Id: interface.h 1.26 2002/05/18 13:43:20 kls Exp $ */ #ifndef __INTERFACE_H #define __INTERFACE_H #include "config.h" -#include "dvbapi.h" +#include "osdbase.h" #include "remote.h" #include "svdrp.h" diff --git a/menu.c b/menu.c index 341cb00e..f294e59c 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.193 2002/05/18 12:35:21 kls Exp $ + * $Id: menu.c 1.194 2002/05/18 13:08:42 kls Exp $ */ #include "menu.h" @@ -2354,7 +2354,7 @@ void cDisplayVolume::Show(void) Interface->Fill(l, 0, p, 1, clrGreen); Interface->Fill(l + p, 0, Width() - l - p, 1, clrWhite); #else - cVolumeBar VolumeBar(Width() * dvbApi->CellWidth(), dvbApi->LineHeight(), Current, Total, Prompt); + cVolumeBar VolumeBar(Width() * cOsd::CellWidth(), cOsd::LineHeight(), Current, Total, Prompt); Interface->SetBitmap(0, 0, VolumeBar); #endif } @@ -2719,7 +2719,7 @@ void cReplayControl::Hide(void) void cReplayControl::DisplayAtBottom(const char *s) { if (s) { - int w = dvbApi->WidthInCells(s); + int w = cOsd::WidthInCells(s); int d = max(Width() - w, 0) / 2; if (modeOnly) //XXX remove when displaying replay mode differently Interface->Fill(0, -1, Interface->Width(), 1, clrTransparent); //XXX remove when displaying replay mode differently @@ -2795,8 +2795,8 @@ bool cReplayControl::ShowProgress(bool Initial) Interface->Fill(0, 1, p, 1, clrGreen); Interface->Fill(p, 1, Width() - p, 1, clrWhite); #else - cProgressBar ProgressBar(Width() * dvbApi->CellWidth(), dvbApi->LineHeight(), Current, Total, marks); - Interface->SetBitmap(0, dvbApi->LineHeight(), ProgressBar); + cProgressBar ProgressBar(Width() * cOsd::CellWidth(), cOsd::LineHeight(), Current, Total, marks); + Interface->SetBitmap(0, cOsd::LineHeight(), ProgressBar); if (!Initial) Interface->Flush(); #endif diff --git a/menuitems.c b/menuitems.c index 4702bcfa..58a57c03 100644 --- a/menuitems.c +++ b/menuitems.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menuitems.c 1.3 2002/05/18 08:53:59 kls Exp $ + * $Id: menuitems.c 1.4 2002/05/18 13:09:04 kls Exp $ */ #include "menuitems.h" @@ -186,18 +186,18 @@ void cMenuEditStrItem::Set(void) strncpy(buf, value, pos); snprintf(buf + pos, sizeof(buf) - pos - 2, fmt, *(value + pos), value + pos + 1); int width = Interface->Width() - Interface->GetCols()[0]; - if (cDvbApi::PrimaryDvbApi->WidthInCells(buf) <= width) { + if (cOsd::WidthInCells(buf) <= width) { // the whole buffer fits on the screen SetValue(buf); return; } - width *= cDvbApi::PrimaryDvbApi->CellWidth(); - width -= cDvbApi::PrimaryDvbApi->Width('>'); // assuming '<' and '>' have the same with + width *= cOsd::CellWidth(); + width -= cOsd::Width('>'); // assuming '<' and '>' have the same with int w = 0; int i = 0; int l = strlen(buf); while (i < l && w <= width) - w += cDvbApi::PrimaryDvbApi->Width(buf[i++]); + w += cOsd::Width(buf[i++]); if (i >= pos + 4) { // the cursor fits on the screen buf[i - 1] = '>'; @@ -214,7 +214,7 @@ void cMenuEditStrItem::Set(void) else i--; while (i >= 0 && w <= width) - w += cDvbApi::PrimaryDvbApi->Width(buf[i--]); + w += cOsd::Width(buf[i--]); buf[++i] = '<'; SetValue(buf + i); } diff --git a/osd.c b/osd.c index 6feeaa87..08b0bf65 100644 --- a/osd.c +++ b/osd.c @@ -4,13 +4,243 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: osd.c 1.25 2002/05/12 11:38:39 kls Exp $ + * $Id: osd.c 1.26 2002/05/18 14:00:21 kls Exp $ */ #include "osd.h" #include +#include "dvbapi.h" #include "i18n.h" +// --- cOsd ------------------------------------------------------------------ + +#ifdef DEBUG_OSD + WINDOW *cOsd::window = NULL; + int cOsd::colorPairs[MaxColorPairs] = { 0 }; +#else + cDvbOsd *cOsd::osd = NULL; +#endif + int cOsd::cols = 0; + int cOsd::rows = 0; + +void cOsd::Initialize(void) +{ +#if defined(DEBUG_OSD) || defined(REMOTE_KBD) + initscr(); + keypad(stdscr, true); + nonl(); + cbreak(); + noecho(); + timeout(10); +#endif +#if defined(DEBUG_OSD) + start_color(); + leaveok(stdscr, true); +#endif +} + +void cOsd::Shutdown(void) +{ + Close(); +#if defined(DEBUG_OSD) || defined(REMOTE_KBD) + endwin(); +#endif +} + +#ifdef DEBUG_OSD +void cOsd::SetColor(eDvbColor colorFg, eDvbColor colorBg) +{ + int color = (colorBg << 16) | colorFg | 0x80000000; + for (int i = 0; i < MaxColorPairs; i++) { + if (!colorPairs[i]) { + colorPairs[i] = color; + init_pair(i + 1, colorFg, colorBg); + wattrset(window, COLOR_PAIR(i + 1)); + break; + } + else if (color == colorPairs[i]) { + wattrset(window, COLOR_PAIR(i + 1)); + break; + } + } +} +#endif + +void cOsd::Open(int w, int h) +{ + int d = (h < 0) ? Setup.OSDheight + h : 0; + h = abs(h); + cols = w; + rows = h; +#ifdef DEBUG_OSD + window = subwin(stdscr, h, w, d, (Setup.OSDwidth - w) / 2); + 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)) + //XXX + SETCOLOR(clrBackground, 0x00, 0x00, 0x00, 127); // background 50% gray + SETCOLOR(clrBlack, 0x00, 0x00, 0x00, 255); + SETCOLOR(clrRed, 0xFC, 0x14, 0x14, 255); + SETCOLOR(clrGreen, 0x24, 0xFC, 0x24, 255); + SETCOLOR(clrYellow, 0xFC, 0xC0, 0x24, 255); + SETCOLOR(clrBlue, 0x00, 0x00, 0xFC, 255); + 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 - w + charWidth) / 2; //TODO PAL vs. NTSC??? + int y = (576 - Setup.OSDheight * lineHeight) / 2 + d; + //XXX + osd = new cDvbOsd(cDvbApi::PrimaryDvbApi->OsdDeviceHandle(), 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 (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 if (d == 0) { //XXX full menu + osd->Create(0, 0, w, lineHeight, 2); + osd->Create(0, lineHeight, w, (Setup.OSDheight - 3) * lineHeight, 2); + osd->AddColor(clrBackground); + osd->AddColor(clrCyan); + osd->AddColor(clrWhite); + osd->AddColor(clrBlack); + osd->Create(0, (Setup.OSDheight - 2) * lineHeight, w, 2 * lineHeight, 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 cOsd::Close(void) +{ +#ifdef DEBUG_OSD + if (window) { + delwin(window); + window = 0; + } +#else + delete osd; + osd = NULL; +#endif +} + +void cOsd::Clear(void) +{ +#ifdef DEBUG_OSD + SetColor(clrBackground, clrBackground); + Fill(0, 0, cols, rows, clrBackground); +#else + osd->Clear(); +#endif +} + +void cOsd::Fill(int x, int y, int w, int h, eDvbColor color) +{ + if (x < 0) x = cols + x; + if (y < 0) y = rows + y; +#ifdef DEBUG_OSD + SetColor(color, color); + for (int r = 0; r < h; r++) { + wmove(window, y + r, x); // ncurses wants 'y' before 'x'! + whline(window, ' ', w); + } + wsyncup(window); // shouldn't be necessary because of 'syncok()', but w/o it doesn't work +#else + osd->Fill(x * charWidth, y * lineHeight, (x + w) * charWidth - 1, (y + h) * lineHeight - 1, color); +#endif +} + +void cOsd::SetBitmap(int x, int y, const cBitmap &Bitmap) +{ +#ifndef DEBUG_OSD + osd->SetBitmap(x, y, Bitmap); +#endif +} + +void cOsd::ClrEol(int x, int y, eDvbColor color) +{ + Fill(x, y, cols - x, 1, color); +} + +int cOsd::CellWidth(void) +{ +#ifdef DEBUG_OSD + return 1; +#else + return charWidth; +#endif +} + +int cOsd::LineHeight(void) +{ +#ifdef DEBUG_OSD + return 1; +#else + return lineHeight; +#endif +} + +int cOsd::Width(unsigned char c) +{ +#ifdef DEBUG_OSD + return 1; +#else + return osd->Width(c); +#endif +} + +int cOsd::WidthInCells(const char *s) +{ +#ifdef DEBUG_OSD + return strlen(s); +#else + return (osd->Width(s) + charWidth - 1) / charWidth; +#endif +} + +eDvbFont cOsd::SetFont(eDvbFont Font) +{ +#ifdef DEBUG_OSD + return Font; +#else + return osd->SetFont(Font); +#endif +} + +void cOsd::Text(int x, int y, const char *s, eDvbColor colorFg, eDvbColor colorBg) +{ + if (x < 0) x = cols + x; + if (y < 0) y = rows + y; +#ifdef DEBUG_OSD + SetColor(colorFg, colorBg); + wmove(window, y, x); // ncurses wants 'y' before 'x'! + waddnstr(window, s, cols - x); +#else + osd->Text(x * charWidth, y * lineHeight, s, colorFg, colorBg); +#endif +} + +void cOsd::Flush(void) +{ +#ifdef DEBUG_OSD + refresh(); +#else + if (osd) + osd->Flush(); +#endif +} + // --- cOsdItem -------------------------------------------------------------- cOsdItem::cOsdItem(eOSState State) diff --git a/osd.h b/osd.h index 174bf099..88c986c8 100644 --- a/osd.h +++ b/osd.h @@ -4,14 +4,19 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: osd.h 1.30 2002/05/18 12:36:30 kls Exp $ + * $Id: osd.h 1.31 2002/05/18 14:00:15 kls Exp $ */ #ifndef __OSD_H #define __OSD_H +#if defined(DEBUG_OSD) || defined(REMOTE_KBD) +#include +#endif #include "config.h" +#include "dvbosd.h" #include "interface.h" +#include "osdbase.h" #include "tools.h" #define MAXOSDITEMS (Setup.OSDheight - 4) @@ -47,6 +52,38 @@ enum eOSState { osUnknown, osUser10, }; +class cOsd { +private: + enum { charWidth = 12, // average character width + lineHeight = 27 // smallest text height + }; +#ifdef DEBUG_OSD + static WINDOW *window; + enum { MaxColorPairs = 16 }; + static int colorPairs[MaxColorPairs]; + static void SetColor(eDvbColor colorFg, eDvbColor colorBg = clrBackground); +#else + static cDvbOsd *osd; +#endif + static int cols, rows; +public: + static void Initialize(void); + static void Shutdown(void); + static void Open(int w, int h); + static void Close(void); + static void Clear(void); + static void Fill(int x, int y, int w, int h, eDvbColor color = clrBackground); + static void SetBitmap(int x, int y, const cBitmap &Bitmap); + static void ClrEol(int x, int y, eDvbColor color = clrBackground); + static int CellWidth(void); + static int LineHeight(void); + static int Width(unsigned char c); + static int WidthInCells(const char *s); + static eDvbFont SetFont(eDvbFont Font); + static void Text(int x, int y, const char *s, eDvbColor colorFg = clrWhite, eDvbColor colorBg = clrBackground); + static void Flush(void); + }; + class cOsdItem : public cListObject { private: const char *text; diff --git a/remote.c b/remote.c index a9fee37c..0ee42a79 100644 --- a/remote.c +++ b/remote.c @@ -6,7 +6,7 @@ * * Ported to LIRC by Carsten Koch 2000-06-16. * - * $Id: remote.c 1.26 2002/05/13 16:31:27 kls Exp $ + * $Id: remote.c 1.27 2002/05/18 12:55:39 kls Exp $ */ #include "remote.h" @@ -24,6 +24,10 @@ #include #endif +#if defined REMOTE_KBD +#include +#endif + #include "config.h" #include "tools.h" diff --git a/vdr.c b/vdr.c index 6d83acce..03aba4ef 100644 --- a/vdr.c +++ b/vdr.c @@ -22,7 +22,7 @@ * * The project's page is at http://www.cadsoft.de/people/kls/vdr * - * $Id: vdr.c 1.111 2002/05/18 12:35:34 kls Exp $ + * $Id: vdr.c 1.112 2002/05/18 14:03:22 kls Exp $ */ #include @@ -36,6 +36,7 @@ #include "i18n.h" #include "interface.h" #include "menu.h" +#include "osd.h" #include "plugin.h" #include "recording.h" #include "tools.h" @@ -322,7 +323,7 @@ int main(int argc, char *argv[]) // DVB interfaces: - if (!cDvbApi::Init()) + if (!cDvbApi::Initialize()) return 2; cDvbApi::SetPrimaryDvbApi(Setup.PrimaryDVB); @@ -334,6 +335,10 @@ int main(int argc, char *argv[]) if (!PluginManager.StartPlugins()) return 2; + // OSD: + + cOsd::Initialize(); + // Channel: Channels.SwitchTo(Setup.CurrentChannel); @@ -592,11 +597,12 @@ int main(int argc, char *argv[]) delete Menu; delete ReplayControl; delete Interface; + cOsd::Shutdown(); PluginManager.Shutdown(true); Setup.CurrentChannel = cDvbApi::CurrentChannel(); Setup.CurrentVolume = cDvbApi::CurrentVolume(); Setup.Save(); - cDvbApi::Cleanup(); + cDvbApi::Shutdown(); if (WatchdogTimeout > 0) dsyslog("max. latency time %d seconds", MaxLatencyTime); isyslog("exiting");