summaryrefslogtreecommitdiff
path: root/PLUGINS/src/skincurses/skincurses.c
diff options
context:
space:
mode:
authorKlaus Schmidinger <kls (at) cadsoft (dot) de>2004-05-31 18:00:00 +0200
committerKlaus Schmidinger <kls (at) cadsoft (dot) de>2004-05-31 18:00:00 +0200
commitb81bf2d1c92e2ac820d2116c66f328869eb627cd (patch)
treea3edee268e9ff1d2e41fb02f8d8b2b8bdef566f4 /PLUGINS/src/skincurses/skincurses.c
parent3c349510b5060ec05a684425b6b2e5b70d67f65c (diff)
downloadvdr-patch-lnbsharing-b81bf2d1c92e2ac820d2116c66f328869eb627cd.tar.gz
vdr-patch-lnbsharing-b81bf2d1c92e2ac820d2116c66f328869eb627cd.tar.bz2
Version 1.3.9vdr-1.3.9
- Completed Croatian language texts (thanks to Drazen Dupor). - New iso8859-2 font to fix the problem with program freezes (thanks to Drazen Dupor). - Implemented a default cRemote::Initialize() that waits 10 seconds for a keypress in order to prevent a "hangup" in case, e.g., the LIRC driver is not loaded (thanks to Helmut Auer). - Updated 'channels.conf.terr' for Hannover (thanks to Peter Waechtler). - cBitmap::DrawBitmap() now also resets the palette if the entire bitmap area is covered (suggested by Sascha Volkenandt). - Fixed setting the title in the replay display of the "Classic VDR" skin in case a shorter title is set after a longer one (thanks to Stefan Huelswitt for reporting this one). - Now using more separate areas in the "ST:TNG Panels" skin to allow a theme to use more independent clrMenu* colors. - Fixed removing the "scanning recordings..." message in case the video directory is empty (thanks to Andreas Regel for reporting this one). - Added SetMessage() functions to the Replay and Channel skin functions. Plugins that implement skins will need to implement these functions. This fixes a missing "Editing process finished" message (thanks to Oliver Endriss for reporting this one). - Fixed the height of the channel display in the "Classic VDR" skin. - Fixed handling descriptor loops in 'libsi', which had sometimes caused invalid CA ids to be added to the channel definitions (thanks to Wayne Keer for reporting this one, and Marcel Wiesweg for fixing it). - Fixed handling colors in cDvbSpuPalette::yuv2rgb() (thanks to Marco Schlüßler). - Made some functions of cFont virtual to allow implementing dummy fonts for the 'curses' skin. - The new plugin 'skincurses' re-implements the functionality that was previously available by compiling VDR with DEBUG_OSD. Some things may not yet work as they should, but it's a starting point.
Diffstat (limited to 'PLUGINS/src/skincurses/skincurses.c')
-rw-r--r--PLUGINS/src/skincurses/skincurses.c724
1 files changed, 724 insertions, 0 deletions
diff --git a/PLUGINS/src/skincurses/skincurses.c b/PLUGINS/src/skincurses/skincurses.c
new file mode 100644
index 0000000..38c297a
--- /dev/null
+++ b/PLUGINS/src/skincurses/skincurses.c
@@ -0,0 +1,724 @@
+/*
+ * skincurses.c: A plugin for the Video Disk Recorder
+ *
+ * See the README file for copyright information and how to reach the author.
+ *
+ * $Id: skincurses.c 1.1 2004/05/31 14:01:49 kls Exp $
+ */
+
+#include <ncurses.h>
+#include <vdr/osd.h>
+#include <vdr/plugin.h>
+#include <vdr/skins.h>
+
+static const char *VERSION = "0.0.1";
+static const char *DESCRIPTION = "A text only skin";
+static const char *MAINMENUENTRY = NULL;
+
+// --- cCursesFont -----------------------------------------------------------
+
+class cCursesFont : public cFont {
+public:
+ cCursesFont(void): cFont(NULL) {}
+ virtual int Width(unsigned char c) const { return 1; }
+ virtual int Width(const char *s) const { return s ? strlen(s) : 0; }
+ virtual int Height(unsigned char c) const { return 1; }
+ virtual int Height(const char *s) const { return 1; }
+ virtual int Height(void) const { return 1; }
+ };
+
+static const cCursesFont Font;
+
+// --- cCursesOsd ------------------------------------------------------------
+
+#define clrBackground COLOR_BLACK
+#define clrTransparent clrBackground
+#define clrBlack clrBackground
+#define clrRed COLOR_RED
+#define clrGreen COLOR_GREEN
+#define clrYellow COLOR_YELLOW
+#define clrBlue COLOR_BLUE
+#define clrMagenta COLOR_MAGENTA
+#define clrCyan COLOR_CYAN
+#define clrWhite COLOR_WHITE
+
+static int clrMessage[] = {
+ clrBlack,
+ clrCyan,
+ clrBlack,
+ clrGreen,
+ clrBlack,
+ clrYellow,
+ clrWhite,
+ clrRed
+ };
+
+#define OsdWidth 50//XXX
+#define OsdHeight 20//XXX
+
+class cCursesOsd : public cOsd {
+private:
+ WINDOW *savedRegion;
+ WINDOW *window;
+ enum { MaxColorPairs = 16 };
+ int colorPairs[MaxColorPairs];
+ void SetColor(int colorFg, int colorBg = clrBackground);
+public:
+ cCursesOsd(int Left, int Top);
+ virtual ~cCursesOsd();
+ virtual void SaveRegion(int x1, int y1, int x2, int y2);
+ virtual void RestoreRegion(void);
+ virtual void DrawText(int x, int y, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width = 0, int Height = 0, int Alignment = taDefault);
+ virtual void DrawRectangle(int x1, int y1, int x2, int y2, tColor Color);
+ virtual void Flush(void);
+ };
+
+cCursesOsd::cCursesOsd(int Left, int Top)
+:cOsd(Left, Top)
+{
+ savedRegion = NULL;
+
+ memset(colorPairs, 0x00, sizeof(colorPairs));
+ start_color();
+ leaveok(stdscr, true);
+
+ window = subwin(stdscr, OsdHeight, OsdWidth, 0, 0);
+ syncok(window, true);
+}
+
+cCursesOsd::~cCursesOsd()
+{
+ if (window) {
+ werase(window);
+ Flush();
+ delwin(window);
+ window = NULL;
+ }
+}
+
+void cCursesOsd::SetColor(int colorFg, int 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);
+ //XXX??? attron(COLOR_PAIR(WHITE_ON_BLUE));
+ wattrset(window, COLOR_PAIR(i + 1));
+ break;
+ }
+ else if (color == colorPairs[i]) {
+ wattrset(window, COLOR_PAIR(i + 1));
+ break;
+ }
+ }
+}
+
+void cCursesOsd::SaveRegion(int x1, int y1, int x2, int y2)
+{
+ if (savedRegion) {
+ delwin(savedRegion);
+ savedRegion = NULL;
+ }
+ savedRegion = newwin(y2 - y1 + 1, x2 - x1 + 1, y1, x1);
+ copywin(window, savedRegion, y1, x1, 0, 0, y2 - y1, x2 - x1, false);
+}
+
+void cCursesOsd::RestoreRegion(void)
+{
+ if (savedRegion) {
+ copywin(savedRegion, window, 0, 0, savedRegion->_begy, savedRegion->_begx, savedRegion->_maxy - savedRegion->_begy, savedRegion->_maxx - savedRegion->_begx, false);
+ delwin(savedRegion);
+ savedRegion = NULL;
+ }
+}
+
+void cCursesOsd::DrawText(int x, int y, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width = 0, int Height = 0, int Alignment = taDefault)
+{
+ int w = Font->Width(s);
+ int h = Font->Height();
+ if (Width || Height) {
+ int cw = Width ? Width : w;
+ int ch = Height ? Height : h;
+ DrawRectangle(x, y, x + cw - 1, y + ch - 1, ColorBg);
+ if (Width) {
+ if ((Alignment & taLeft) != 0)
+ ;
+ else if ((Alignment & taRight) != 0) {
+ if (w < Width)
+ x += Width - w;
+ }
+ else { // taCentered
+ if (w < Width)
+ x += (Width - w) / 2;
+ }
+ }
+ if (Height) {
+ if ((Alignment & taTop) != 0)
+ ;
+ else if ((Alignment & taBottom) != 0) {
+ if (h < Height)
+ y += Height - h;
+ }
+ else { // taCentered
+ if (h < Height)
+ y += (Height - h) / 2;
+ }
+ }
+ }
+ SetColor(ColorFg, ColorBg);
+ wmove(window, y, x); // ncurses wants 'y' before 'x'!
+ waddnstr(window, s, OsdWidth - x);
+}
+
+void cCursesOsd::DrawRectangle(int x1, int y1, int x2, int y2, tColor Color)
+{
+ SetColor(Color, Color);
+ for (int y = y1; y <= y2; y++) {
+ wmove(window, y, x1); // ncurses wants 'y' before 'x'!
+ whline(window, ' ', x2 - x1 + 1);
+ }
+ wsyncup(window); // shouldn't be necessary because of 'syncok()', but w/o it doesn't work
+}
+
+void cCursesOsd::Flush(void)
+{
+ refresh();
+}
+
+// --- cSkinCursesDisplayChannel ---------------------------------------------
+
+class cSkinCursesDisplayChannel : public cSkinDisplayChannel {
+private:
+ cOsd *osd;
+ int timeWidth;
+ bool message;
+public:
+ cSkinCursesDisplayChannel(bool WithInfo);
+ virtual ~cSkinCursesDisplayChannel();
+ virtual void SetChannel(const cChannel *Channel, int Number);
+ virtual void SetEvents(const cEvent *Present, const cEvent *Following);
+ virtual void SetMessage(eMessageType Type, const char *Text);
+ virtual void Flush(void);
+ };
+
+cSkinCursesDisplayChannel::cSkinCursesDisplayChannel(bool WithInfo)
+{
+ int Lines = WithInfo ? 5 : 1;
+ message = false;
+ osd = new cCursesOsd(0, Setup.ChannelInfoPos ? 0 : OsdHeight - Lines);
+ timeWidth = strlen("00:00");
+ osd->DrawRectangle(0, 0, OsdWidth - 1, Lines - 1, clrBackground);
+}
+
+cSkinCursesDisplayChannel::~cSkinCursesDisplayChannel()
+{
+ delete osd;
+}
+
+void cSkinCursesDisplayChannel::SetChannel(const cChannel *Channel, int Number)
+{
+ osd->DrawRectangle(0, 0, OsdWidth - 1, 0, clrBackground);
+ osd->DrawText(0, 0, ChannelString(Channel, Number), clrWhite, clrBackground, &Font);
+}
+
+void cSkinCursesDisplayChannel::SetEvents(const cEvent *Present, const cEvent *Following)
+{
+ osd->DrawRectangle(0, 1, timeWidth - 1, 4, clrRed);
+ osd->DrawRectangle(timeWidth, 1, OsdWidth - 1, 4, clrBackground);
+ for (int i = 0; i < 2; i++) {
+ const cEvent *e = !i ? Present : Following;
+ if (e) {
+ osd->DrawText( 0, 2 * i + 1, e->GetTimeString(), clrWhite, clrRed, &Font);
+ osd->DrawText(timeWidth + 1, 2 * i + 1, e->Title(), clrCyan, clrBackground, &Font);
+ osd->DrawText(timeWidth + 1, 2 * i + 2, e->ShortText(), clrYellow, clrBackground, &Font);
+ }
+ }
+}
+
+void cSkinCursesDisplayChannel::SetMessage(eMessageType Type, const char *Text)
+{
+ if (Text) {
+ osd->SaveRegion(0, 0, OsdWidth - 1, 0);
+ osd->DrawText(0, 0, Text, clrMessage[2 * Type], clrMessage[2 * Type + 1], &Font, OsdWidth, 0, taCenter);
+ message = true;
+ }
+ else {
+ osd->RestoreRegion();
+ message = false;
+ }
+}
+
+void cSkinCursesDisplayChannel::Flush(void)
+{
+ if (!message) {
+ const char *date = DayDateTime();
+ osd->DrawText(OsdWidth - strlen(date), 0, date, clrWhite, clrBackground, &Font);
+ }
+ osd->Flush();
+}
+
+// --- cSkinCursesDisplayMenu ------------------------------------------------
+
+class cSkinCursesDisplayMenu : public cSkinDisplayMenu {
+private:
+ cOsd *osd;
+ void SetScrollbar(void);
+public:
+ cSkinCursesDisplayMenu(void);
+ virtual ~cSkinCursesDisplayMenu();
+ virtual void Scroll(bool Up, bool Page);
+ virtual int MaxItems(void);
+ virtual void Clear(void);
+ virtual void SetTitle(const char *Title);
+ virtual void SetButtons(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL);
+ virtual void SetMessage(eMessageType Type, const char *Text);
+ virtual void SetItem(const char *Text, int Index, bool Current, bool Selectable);
+ virtual void SetEvent(const cEvent *Event);
+ virtual void SetRecording(const cRecording *Recording);
+ virtual void SetText(const char *Text, bool FixedFont);
+ virtual void Flush(void);
+ };
+
+cSkinCursesDisplayMenu::cSkinCursesDisplayMenu(void)
+{
+ osd = new cCursesOsd(0, 0);
+ osd->DrawRectangle(0, 0, OsdWidth - 1, OsdHeight - 1, clrBackground);
+}
+
+cSkinCursesDisplayMenu::~cSkinCursesDisplayMenu()
+{
+ delete osd;
+}
+
+void cSkinCursesDisplayMenu::SetScrollbar(void)
+{
+ if (textScroller.CanScroll()) {
+ int yt = textScroller.Top();
+ int yb = yt + textScroller.Height() - 1;
+ int st = yt;
+ int sb = yb;
+ int tt = st + (sb - st) * textScroller.Offset() / textScroller.Total();
+ int tb = tt + (sb - st) * textScroller.Shown() / textScroller.Total();
+ int xl = OsdWidth - 1;
+ osd->DrawRectangle(xl, st, xl, sb, clrCyan);
+ osd->DrawRectangle(xl, tt, xl, tb, clrWhite);
+ }
+}
+
+void cSkinCursesDisplayMenu::Scroll(bool Up, bool Page)
+{
+ cSkinDisplayMenu::Scroll(Up, Page);
+ SetScrollbar();
+}
+
+int cSkinCursesDisplayMenu::MaxItems(void)
+{
+ return OsdHeight - 4;
+}
+
+void cSkinCursesDisplayMenu::Clear(void)
+{
+ osd->DrawRectangle(0, 1, OsdWidth - 1, OsdHeight - 2, clrBackground);
+ textScroller.Reset();
+}
+
+void cSkinCursesDisplayMenu::SetTitle(const char *Title)
+{
+ osd->DrawText(0, 0, Title, clrBlack, clrCyan, &Font, OsdWidth);
+}
+
+void cSkinCursesDisplayMenu::SetButtons(const char *Red, const char *Green, const char *Yellow, const char *Blue)
+{
+ int w = OsdWidth;
+ int t0 = 0;
+ int t1 = 0 + w / 4;
+ int t2 = 0 + w / 2;
+ int t3 = w - w / 4;
+ int t4 = w;
+ int y = OsdHeight - 1;
+ osd->DrawText(t0, y, Red, clrWhite, Red ? clrRed : clrBackground, &Font, t1 - t0, 0, taCenter);
+ osd->DrawText(t1, y, Green, clrBlack, Green ? clrGreen : clrBackground, &Font, t2 - t1, 0, taCenter);
+ osd->DrawText(t2, y, Yellow, clrBlack, Yellow ? clrYellow : clrBackground, &Font, t3 - t2, 0, taCenter);
+ osd->DrawText(t3, y, Blue, clrWhite, Blue ? clrBlue : clrBackground, &Font, t4 - t3, 0, taCenter);
+}
+
+void cSkinCursesDisplayMenu::SetMessage(eMessageType Type, const char *Text)
+{
+ if (Text)
+ osd->DrawText(0, OsdHeight - 2, Text, clrMessage[2 * Type], clrMessage[2 * Type + 1], &Font, OsdWidth, 0, taCenter);
+ else
+ osd->DrawRectangle(0, OsdHeight - 2, OsdWidth - 1, OsdHeight - 2, clrBackground);
+}
+
+void cSkinCursesDisplayMenu::SetItem(const char *Text, int Index, bool Current, bool Selectable)
+{
+ int y = 2 + Index;
+ int ColorFg, ColorBg;
+ if (Current) {
+ ColorFg = clrBlack;
+ ColorBg = clrCyan;
+ }
+ else {
+ ColorFg = Selectable ? clrWhite : clrCyan;
+ ColorBg = clrBackground;
+ }
+ for (int i = 0; i < MaxTabs; i++) {
+ const char *s = GetTabbedText(Text, i);
+ if (s) {
+ int xt = Tab(i);
+ osd->DrawText(xt, y, s, ColorFg, ColorBg, &Font, OsdWidth - xt);
+ }
+ if (!Tab(i + 1))
+ break;
+ }
+ SetEditableWidth(OsdWidth - Tab(1));
+}
+
+void cSkinCursesDisplayMenu::SetEvent(const cEvent *Event)
+{
+ if (!Event)
+ return;
+ int y = 2;
+ cTextScroller ts;
+ char t[32];
+ snprintf(t, sizeof(t), "%s %s - %s", Event->GetDateString(), Event->GetTimeString(), Event->GetEndTimeString());
+ ts.Set(osd, 0, y, OsdWidth, OsdHeight - y - 2, t, &Font, clrYellow, clrBackground);
+ if (Event->Vps() && Event->Vps() != Event->StartTime()) {
+ char *buffer;
+ asprintf(&buffer, " VPS: %s", Event->GetVpsString());
+ osd->DrawText(OsdWidth - strlen(buffer), y, buffer, clrBlack, clrYellow, &Font);
+ free(buffer);
+ }
+ y += ts.Height();
+ y += 1;
+ ts.Set(osd, 0, y, OsdWidth, OsdHeight - y - 2, Event->Title(), &Font, clrCyan, clrBackground);
+ y += ts.Height();
+ if (!isempty(Event->ShortText())) {
+ ts.Set(osd, 0, y, OsdWidth, OsdHeight - y - 2, Event->ShortText(), &Font, clrYellow, clrBackground);
+ y += ts.Height();
+ }
+ y += 1;
+ if (!isempty(Event->Description())) {
+ textScroller.Set(osd, 0, y, OsdWidth - 2, OsdHeight - y - 2, Event->Description(), &Font, clrCyan, clrBackground);
+ SetScrollbar();
+ }
+}
+
+void cSkinCursesDisplayMenu::SetRecording(const cRecording *Recording)
+{
+ SetText(Recording->Summary(), false); //TODO
+}
+
+void cSkinCursesDisplayMenu::SetText(const char *Text, bool FixedFont)
+{
+ textScroller.Set(osd, 0, 2, OsdWidth - 2, OsdHeight - 4, Text, &Font, clrWhite, clrBackground);
+ SetScrollbar();
+}
+
+void cSkinCursesDisplayMenu::Flush(void)
+{
+ const char *date = DayDateTime();
+ osd->DrawText(OsdWidth - strlen(date) - 2, 0, date, clrBlack, clrCyan, &Font);
+ osd->Flush();
+}
+
+// --- cSkinCursesDisplayReplay ----------------------------------------------
+
+class cSkinCursesDisplayReplay : public cSkinDisplayReplay {
+private:
+ cOsd *osd;
+ bool message;
+public:
+ cSkinCursesDisplayReplay(bool ModeOnly);
+ virtual ~cSkinCursesDisplayReplay();
+ virtual void SetTitle(const char *Title);
+ virtual void SetMode(bool Play, bool Forward, int Speed);
+ virtual void SetProgress(int Current, int Total);
+ virtual void SetCurrent(const char *Current);
+ virtual void SetTotal(const char *Total);
+ virtual void SetJump(const char *Jump);
+ virtual void SetMessage(eMessageType Type, const char *Text);
+ virtual void Flush(void);
+ };
+
+cSkinCursesDisplayReplay::cSkinCursesDisplayReplay(bool ModeOnly)
+{
+ message = false;
+ osd = new cCursesOsd(0, OsdHeight - 3);
+ osd->DrawRectangle(0, 0, OsdWidth - 1, 2, ModeOnly ? clrTransparent : clrBackground);
+}
+
+cSkinCursesDisplayReplay::~cSkinCursesDisplayReplay()
+{
+ delete osd;
+}
+
+void cSkinCursesDisplayReplay::SetTitle(const char *Title)
+{
+ osd->DrawText(0, 0, Title, clrWhite, clrBackground, &Font, OsdWidth);
+}
+
+void cSkinCursesDisplayReplay::SetMode(bool Play, bool Forward, int Speed)
+{
+ if (Setup.ShowReplayMode) {
+ const char *Mode;
+ if (Speed == -1) Mode = Play ? " > " : " || ";
+ else if (Play) Mode = Forward ? " X>> " : " <<X ";
+ else Mode = Forward ? " X|> " : " <|X ";
+ char buf[16];
+ strn0cpy(buf, Mode, sizeof(buf));
+ char *p = strchr(buf, 'X');
+ if (p)
+ *p = Speed > 0 ? '1' + Speed - 1 : ' ';
+ SetJump(buf);
+ }
+}
+
+void cSkinCursesDisplayReplay::SetProgress(int Current, int Total)
+{
+ int p = OsdWidth * Current / Total;
+ osd->DrawRectangle(0, 1, p, 1, clrGreen);
+ osd->DrawRectangle(p, 1, OsdWidth, 1, clrWhite);
+}
+
+void cSkinCursesDisplayReplay::SetCurrent(const char *Current)
+{
+ osd->DrawText(0, 2, Current, clrWhite, clrBackground, &Font, strlen(Current) + 3);
+}
+
+void cSkinCursesDisplayReplay::SetTotal(const char *Total)
+{
+ osd->DrawText(OsdWidth - strlen(Total), 2, Total, clrWhite, clrBackground, &Font);
+}
+
+void cSkinCursesDisplayReplay::SetJump(const char *Jump)
+{
+ osd->DrawText(OsdWidth / 4, 2, Jump, clrWhite, clrBackground, &Font, OsdWidth / 2, 0, taCenter);
+}
+
+void cSkinCursesDisplayReplay::SetMessage(eMessageType Type, const char *Text)
+{
+ if (Text) {
+ osd->SaveRegion(0, 2, OsdWidth - 1, 2);
+ osd->DrawText(0, 2, Text, clrMessage[2 * Type], clrMessage[2 * Type + 1], &Font, OsdWidth, 0, taCenter);
+ message = true;
+ }
+ else {
+ osd->RestoreRegion();
+ message = false;
+ }
+}
+
+void cSkinCursesDisplayReplay::Flush(void)
+{
+ osd->Flush();
+}
+
+// --- cSkinCursesDisplayVolume ----------------------------------------------
+
+class cSkinCursesDisplayVolume : public cSkinDisplayVolume {
+private:
+ cOsd *osd;
+public:
+ cSkinCursesDisplayVolume(void);
+ virtual ~cSkinCursesDisplayVolume();
+ virtual void SetVolume(int Current, int Total, bool Mute);
+ virtual void Flush(void);
+ };
+
+cSkinCursesDisplayVolume::cSkinCursesDisplayVolume(void)
+{
+ osd = new cCursesOsd(0, OsdHeight - 1);
+}
+
+cSkinCursesDisplayVolume::~cSkinCursesDisplayVolume()
+{
+ delete osd;
+}
+
+void cSkinCursesDisplayVolume::SetVolume(int Current, int Total, bool Mute)
+{
+ if (Mute) {
+ osd->DrawRectangle(0, 0, OsdWidth - 1, 0, clrTransparent);
+ osd->DrawText(0, 0, tr("Mute"), clrGreen, clrBackground, &Font);
+ }
+ else {
+ const char *Prompt = tr("Volume ");
+ int l = strlen(Prompt);
+ int p = (OsdWidth - l) * Current / Total;
+ osd->DrawText(0, 0, Prompt, clrGreen, clrBackground, &Font);
+ osd->DrawRectangle(l, 0, l + p - 1, 0, clrGreen);
+ osd->DrawRectangle(l + p, 0, OsdWidth - 1, 0, clrWhite);
+ }
+}
+
+void cSkinCursesDisplayVolume::Flush(void)
+{
+ osd->Flush();
+}
+
+// --- cSkinCursesDisplayMessage ---------------------------------------------
+
+class cSkinCursesDisplayMessage : public cSkinDisplayMessage {
+private:
+ cOsd *osd;
+public:
+ cSkinCursesDisplayMessage(void);
+ virtual ~cSkinCursesDisplayMessage();
+ virtual void SetMessage(eMessageType Type, const char *Text);
+ virtual void Flush(void);
+ };
+
+cSkinCursesDisplayMessage::cSkinCursesDisplayMessage(void)
+{
+ osd = new cCursesOsd(0, OsdHeight - 1);
+}
+
+cSkinCursesDisplayMessage::~cSkinCursesDisplayMessage()
+{
+ delete osd;
+}
+
+void cSkinCursesDisplayMessage::SetMessage(eMessageType Type, const char *Text)
+{
+ osd->DrawText(0, 0, Text, clrMessage[2 * Type], clrMessage[2 * Type + 1], &Font, OsdWidth, 0, taCenter);
+}
+
+void cSkinCursesDisplayMessage::Flush(void)
+{
+ osd->Flush();
+}
+
+// --- cSkinCurses -----------------------------------------------------------
+
+class cSkinCurses : public cSkin {
+public:
+ cSkinCurses(void);
+ virtual const char *Description(void);
+ virtual cSkinDisplayChannel *DisplayChannel(bool WithInfo);
+ virtual cSkinDisplayMenu *DisplayMenu(void);
+ virtual cSkinDisplayReplay *DisplayReplay(bool ModeOnly);
+ virtual cSkinDisplayVolume *DisplayVolume(void);
+ virtual cSkinDisplayMessage *DisplayMessage(void);
+ };
+
+cSkinCurses::cSkinCurses(void)
+:cSkin("curses")
+{
+}
+
+const char *cSkinCurses::Description(void)
+{
+ return tr("Text mode");
+}
+
+cSkinDisplayChannel *cSkinCurses::DisplayChannel(bool WithInfo)
+{
+ return new cSkinCursesDisplayChannel(WithInfo);
+}
+
+cSkinDisplayMenu *cSkinCurses::DisplayMenu(void)
+{
+ return new cSkinCursesDisplayMenu;
+}
+
+cSkinDisplayReplay *cSkinCurses::DisplayReplay(bool ModeOnly)
+{
+ return new cSkinCursesDisplayReplay(ModeOnly);
+}
+
+cSkinDisplayVolume *cSkinCurses::DisplayVolume(void)
+{
+ return new cSkinCursesDisplayVolume;
+}
+
+cSkinDisplayMessage *cSkinCurses::DisplayMessage(void)
+{
+ return new cSkinCursesDisplayMessage;
+}
+
+// --- cPluginSkinCurses -----------------------------------------------------
+
+class cPluginSkinCurses : public cPlugin {
+private:
+ // Add any member variables or functions you may need here.
+public:
+ cPluginSkinCurses(void);
+ virtual ~cPluginSkinCurses();
+ virtual const char *Version(void) { return VERSION; }
+ virtual const char *Description(void) { return DESCRIPTION; }
+ virtual const char *CommandLineHelp(void);
+ virtual bool ProcessArgs(int argc, char *argv[]);
+ virtual bool Initialize(void);
+ virtual bool Start(void);
+ virtual void Housekeeping(void);
+ virtual const char *MainMenuEntry(void) { return MAINMENUENTRY; }
+ virtual cOsdObject *MainMenuAction(void);
+ virtual cMenuSetupPage *SetupMenu(void);
+ virtual bool SetupParse(const char *Name, const char *Value);
+ };
+
+cPluginSkinCurses::cPluginSkinCurses(void)
+{
+ // Initialize any member variables here.
+ // DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL
+ // VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
+}
+
+cPluginSkinCurses::~cPluginSkinCurses()
+{
+ // Clean up after yourself!
+ endwin();
+}
+
+const char *cPluginSkinCurses::CommandLineHelp(void)
+{
+ // Return a string that describes all known command line options.
+ return NULL;
+}
+
+bool cPluginSkinCurses::ProcessArgs(int argc, char *argv[])
+{
+ // Implement command line argument processing here if applicable.
+ return true;
+}
+
+bool cPluginSkinCurses::Initialize(void)
+{
+ // Initialize any background activities the plugin shall perform.
+ initscr();
+ return true;
+}
+
+bool cPluginSkinCurses::Start(void)
+{
+ // Start any background activities the plugin shall perform.
+ new cSkinCurses;
+ return true;
+}
+
+void cPluginSkinCurses::Housekeeping(void)
+{
+ // Perform any cleanup or other regular tasks.
+}
+
+cOsdObject *cPluginSkinCurses::MainMenuAction(void)
+{
+ // Perform the action when selected from the main VDR menu.
+ return NULL;
+}
+
+cMenuSetupPage *cPluginSkinCurses::SetupMenu(void)
+{
+ // Return a setup menu in case the plugin supports one.
+ return NULL;
+}
+
+bool cPluginSkinCurses::SetupParse(const char *Name, const char *Value)
+{
+ // Parse your own setup parameters and store their values.
+ return false;
+}
+
+VDRPLUGINCREATOR(cPluginSkinCurses); // Don't touch this!