summaryrefslogtreecommitdiff
path: root/PLUGINS/src/skincurses/skincurses.c
diff options
context:
space:
mode:
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!