diff options
author | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2004-05-16 18:00:00 +0200 |
---|---|---|
committer | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2004-05-16 18:00:00 +0200 |
commit | c80a53ff6ea22aa14d1f9772b310b77ea0da7c42 (patch) | |
tree | c2c6d9dc5c939765abc61fb0f19de00f988aecc9 /interface.c | |
parent | 9384e56566f56e77d577319a42929e708936e7c7 (diff) | |
download | vdr-patch-lnbsharing-vdr-1.3.7.tar.gz vdr-patch-lnbsharing-vdr-1.3.7.tar.bz2 |
Version 1.3.7vdr-1.3.7
- Fixed a memory leak in thread handling when using NPTL (thanks to Jon Burgess).
- Fixed handling Setup.RecordDolbyDigital, which was broken since version 1.1.6.
- Fixed handling text lengths for itemized EPG texts (thanks to Marcel Wiesweg).
- Fixed the help for LSTE and LSTR (was broken in 1.3.6).
- Improved iso8859-7 fonts (thanks to Dimitrios Dimitrakos).
- Added some 3-letter language codes (thanks to Marcus Mönnig).
- Added language code handling to the subtitling descriptor in 'libsi' (thanks to
Pekka Virtanen).
- Moved several menu item classes from menu.c to menuitems.[hc] to make them
available for plugins.
- The epg2html.pl script now handles '|' in description texts.
- The new setup option "OSD/Use small font" can be used to control the use of
the small font (see MANUAL for details).
- Swapped osd.[hc] and osdbase.[hc] to have the virtual OSD base class named cOsd.
Plugins may need to adjust their #include statements.
- Colors are now given as AARRGGBB instead of AABBGGRR. The values are mapped to
the driver's (wrong) sequence in dvbosd.c (this should really be fixed in the
driver, together with the endian problem).
- The new OSD setup parameters "Left" and "Top" can be used to define the top left
corner of the OSD.
- The OSD size parameters are now in pixel (as opposed to formerly characters).
When reading a 'setup.conf' file from an older version of VDR, the OSDwidth
and OSDheight values will be converted to pixel automatically.
- The OSD is now fully device independent. See the comments in VDR/osd.h and the
description in PLUGINS.html for information on how a plugin can implement an OSD
display on arbitrary hardware.
- The OSD (actually its cBitmap class) can now handle XPM files. There are several
XPM files in the VDR/symbols directory which can be used by skins (some of these
have been taken from the "elchi" patch). See VDR/skinsttng.c for examples on how
to use these.
- Due to the changes in the OSD handling the DEBUG_OSD option for a textual OSD
has been dropped. There will be a plugin that implements a skin with this
functionality later.
- The entire OSD display can now be implemented via "skins". See VDR/skins.[hc],
VDR/skinclassic.[hc], VDR/skinsttng.[hc] and PLUGINS.html for information on how
a plugin can implement its own skin. By default VDR comes with a "Classic" skin
that implements the OSD display known from previous versions, and the new skin
named "ST:TNG Panels", which is also the default skin now. The actual skin can
be selected through "Setup/OSD/Skin".
- The colors used in a skin can now be configured using "themes". See PLUGINS.html
for information on how a skin can make use of themes, and man vdr(5) for the
structure of a theme file. The actual theme to use can be selected through
"Setup/OSD/Theme".
- Added Croatian language texts (thanks to Drazen Dupor).
NOTE: there is apparently a problem with the newly introduced iso8859-2 font,
because as soon as Setup/OSD/Language is set to Croatian (currently the last one
in the list) everything freezes and the vdr processes have to be killed with -9
and the driver needs to be reloaded. Maybe somebody else can find out what's
going wrong here...
- Added missing NULL checks when accessing sectionHandler in device.c (thanks to
Pekka Virtanen).
- Fixed setting the time from the DVB data stream (thanks to Helmut Auer for
pointing out a frequency/transponder handling mixup). This now also takes the
actual source (sat, cable etc.) into account. Please go into "Setup/EPG" and
set the "Set system time" and "Use time from transponder" parameters accordingly
(this is necessary even if you have already set them before!).
Diffstat (limited to 'interface.c')
-rw-r--r-- | interface.c | 341 |
1 files changed, 42 insertions, 299 deletions
diff --git a/interface.c b/interface.c index a0ee9cc..06ba331 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.66 2003/10/24 14:38:08 kls Exp $ + * $Id: interface.c 1.67 2004/05/02 10:57:06 kls Exp $ */ #include "interface.h" @@ -12,16 +12,12 @@ #include <stdlib.h> #include <unistd.h> #include "i18n.h" -#include "osd.h" #include "status.h" cInterface *Interface = NULL; cInterface::cInterface(int SVDRPport) { - open = 0; - cols[0] = 0; - width = height = 0; interrupted = false; SVDRP = NULL; if (SVDRPport) @@ -33,38 +29,17 @@ cInterface::~cInterface() delete SVDRP; } -void cInterface::Open(int NumCols, int NumLines) -{ - if (!open++) { - if (NumCols == 0) - NumCols = Setup.OSDwidth; - if (NumLines == 0) - NumLines = Setup.OSDheight; - cOsd::Open(width = NumCols, height = NumLines); - } -} - -void cInterface::Close(void) -{ - if (open == 1) - Clear(); - if (!--open) { - cOsd::Close(); - width = height = 0; - } -} - eKeys cInterface::GetKey(bool Wait) { if (!cRemote::HasKeys()) - Flush(); + Skins.Flush(); if (SVDRP) { if (SVDRP->Process()) Wait = false; - if (!open) { + if (!Skins.IsOpen()) { char *message = SVDRP->GetMessage(); if (message) { - Info(message); + Skins.Message(mtInfo, message); free(message); } } @@ -76,7 +51,7 @@ eKeys cInterface::Wait(int Seconds, bool KeepChar) { if (Seconds == 0) Seconds = Setup.OSDMessageTime; - Flush(); + Skins.Flush(); eKeys Key = kNone; time_t timeout = time(NULL) + Seconds; for (;;) { @@ -90,267 +65,37 @@ eKeys cInterface::Wait(int Seconds, bool KeepChar) return Key; } -void cInterface::Clear(void) -{ - if (open) - cOsd::Clear(); - cStatus::MsgOsdClear(); -} - -void cInterface::ClearEol(int x, int y, eDvbColor Color) -{ - if (open) - cOsd::ClrEol(x, y, Color); -} - -void cInterface::Fill(int x, int y, int w, int h, eDvbColor Color) -{ - if (open) - cOsd::Fill(x, y, w, h, Color); -} - -void cInterface::SetBitmap(int x, int y, const cBitmap &Bitmap) -{ - if (open) - cOsd::SetBitmap(x, y, Bitmap); -} - -void cInterface::Flush(void) -{ - if (open) - cOsd::Flush(); -} - -void cInterface::SetCols(int *c) -{ - for (int i = 0; i < MaxCols; i++) { - cols[i] = *c++; - if (cols[i] == 0) - break; - } -} - -eDvbFont cInterface::SetFont(eDvbFont Font) -{ - return cOsd::SetFont(Font); -} - -char *cInterface::WrapText(const char *Text, int Width, int *Height) -{ - // Wraps the Text to make it fit into the area defined by the given Width - // (which is given in character cells). - // The actual number of lines resulting from this operation is returned in - // Height. - // The returned string is newly created on the heap and the caller - // is responsible for deleting it once it is no longer used. - // Wrapping is done by inserting the necessary number of newline - // characters into the string. - - int Lines = 1; - char *t = strdup(Text); - char *Blank = NULL; - char *Delim = NULL; - int w = 0; - - Width *= cOsd::CellWidth(); - - while (*t && t[strlen(t) - 1] == '\n') - t[strlen(t) - 1] = 0; // skips trailing newlines - - for (char *p = t; *p; ) { - if (*p == '|') - *p = '\n'; - if (*p == '\n') { - Lines++; - w = 0; - Blank = Delim = NULL; - p++; - continue; - } - else if (isspace(*p)) - Blank = p; - int cw = cOsd::Width(*p); - if (w + cw > Width) { - if (Blank) { - *Blank = '\n'; - p = Blank; - continue; - } - else { - // Here's the ugly part, where we don't have any whitespace to - // punch in a newline, so we need to make room for it: - if (Delim) - p = Delim + 1; // let's fall back to the most recent delimiter - char *s = MALLOC(char, strlen(t) + 2); // The additional '\n' plus the terminating '\0' - int l = p - t; - strncpy(s, t, l); - s[l] = '\n'; - strcpy(s + l + 1, p); - free(t); - t = s; - p = t + l; - continue; - } - } - else - w += cw; - if (strchr("-.,:;!?_", *p)) { - Delim = p; - Blank = NULL; - } - p++; - } - - *Height = Lines; - return t; -} - -void cInterface::Write(int x, int y, const char *s, eDvbColor FgColor, eDvbColor BgColor) -{ - if (open) - cOsd::Text(x, y, s, FgColor, BgColor); -} - -void cInterface::WriteText(int x, int y, const char *s, eDvbColor FgColor, eDvbColor BgColor) -{ - if (open) { - ClearEol(x, y, BgColor); - int col = 0; - for (;;) { - const char *t = strchr(s, '\t'); - const char *p = s; - char buf[1000]; - if (t && col < MaxCols && cols[col] > 0) { - unsigned int n = t - s; - if (n >= sizeof(buf)) - n = sizeof(buf) - 1; - strncpy(buf, s, n); - buf[n] = 0; - p = buf; - s = t + 1; - } - Write(x, y, p, FgColor, BgColor); - if (p == s) - break; - x += cols[col++]; - } - } -} - -void cInterface::Title(const char *s) -{ - ClearEol(0, 0, clrCyan); - const char *t = strchr(s, '\t'); - if (t) { - char buffer[Width() + 1]; - unsigned int n = t - s; - if (n >= sizeof(buffer)) - n = sizeof(buffer) - 1; - strn0cpy(buffer, s, n + 1); - Write(1, 0, buffer, clrBlack, clrCyan); - t++; - Write(-(cOsd::WidthInCells(t) + 1), 0, t, clrBlack, clrCyan); - } - else { - int x = (Width() - strlen(s)) / 2; - if (x < 0) - x = 0; - Write(x, 0, s, clrBlack, clrCyan); - } - cStatus::MsgOsdTitle(s); -} - -void cInterface::Status(const char *s, eDvbColor FgColor, eDvbColor BgColor) -{ - int Line = (abs(height) == 1) ? 0 : -2; - ClearEol(0, Line, s ? BgColor : clrBackground); - if (s) { - int x = (Width() - int(strlen(s))) / 2; - if (x < 0) - x = 0; - Write(x, Line, s, FgColor, BgColor); - } - cStatus::MsgOsdStatusMessage(s); -} - -void cInterface::Info(const char *s) -{ - Open(Setup.OSDwidth, -1); - isyslog("info: %s", s); - Status(s, clrBlack, clrGreen); - Wait(); - Status(NULL); - Close(); -} - -void cInterface::Error(const char *s) -{ - Open(Setup.OSDwidth, -1); - esyslog("ERROR: %s", s); - Status(s, clrWhite, clrRed); - Wait(); - Status(NULL); - Close(); -} - bool cInterface::Confirm(const char *s, int Seconds, bool WaitForTimeout) { - Open(Setup.OSDwidth, -1); isyslog("confirm: %s", s); - Status(s, clrBlack, clrYellow); - eKeys k = Wait(Seconds); + eKeys k = Skins.Message(mtWarning, s, Seconds); bool result = WaitForTimeout ? k == kNone : k == kOk; - Status(NULL); - Close(); isyslog("%sconfirmed", result ? "" : "not "); return result; } -void cInterface::HelpButton(int Index, const char *Text, eDvbColor FgColor, eDvbColor BgColor) -{ - if (open) { - const int w = Width() / 4; - cOsd::Fill(Index * w, -1, w, 1, Text ? BgColor : clrBackground); - if (Text) { - int l = (w - int(strlen(Text))) / 2; - if (l < 0) - l = 0; - cOsd::Text(Index * w + l, -1, Text, FgColor, BgColor); - } - } -} - -void cInterface::Help(const char *Red, const char *Green, const char *Yellow, const char *Blue) -{ - HelpButton(0, Red, clrBlack, clrRed); - HelpButton(1, Green, clrBlack, clrGreen); - HelpButton(2, Yellow, clrBlack, clrYellow); - HelpButton(3, Blue, clrWhite, clrBlue); - cStatus::MsgOsdHelpKeys(Red, Green, Yellow, Blue); -} - -bool cInterface::QueryKeys(cRemote *Remote) +bool cInterface::QueryKeys(cRemote *Remote, cSkinDisplayMenu *DisplayMenu) { - WriteText(1, 3, tr("Phase 1: Detecting RC code type")); - WriteText(1, 5, tr("Press any key on the RC unit")); - Flush(); + DisplayMenu->SetItem(tr("Phase 1: Detecting RC code type"), 1, false, false); + DisplayMenu->SetItem(tr("Press any key on the RC unit"), 3, false, false); + DisplayMenu->Flush(); if (Remote->Initialize()) { - WriteText(1, 5, tr("RC code detected!")); - WriteText(1, 6, tr("Do not press any key...")); - Flush(); + DisplayMenu->SetItem(tr("RC code detected!"), 3, false, false); + DisplayMenu->SetItem(tr("Do not press any key..."), 4, false, false); + DisplayMenu->Flush(); sleep(3); - ClearEol(0, 5); - ClearEol(0, 6); + DisplayMenu->SetItem("", 3, false, false); + DisplayMenu->SetItem("", 4, false, false); - WriteText(1, 3, tr("Phase 2: Learning specific key codes")); + DisplayMenu->SetItem(tr("Phase 2: Learning specific key codes"), 1, false, false); eKeys NewKey = kUp; while (NewKey != kNone) { char *Prompt; asprintf(&Prompt, tr("Press key for '%s'"), tr(cKey::ToString(NewKey))); - WriteText(1, 5, Prompt); + DisplayMenu->SetItem(Prompt, 3, false, false); free(Prompt); cRemote::Clear(); - Flush(); + DisplayMenu->Flush(); for (eKeys k = NewKey; k == NewKey; ) { char *NewCode = NULL; eKeys Key = cRemote::Get(100, &NewCode); @@ -362,20 +107,20 @@ bool cInterface::QueryKeys(cRemote *Remote) Keys.Del(last); } break; - case kDown: WriteText(1, 5, tr("Press 'Up' to confirm")); - WriteText(1, 6, tr("Press 'Down' to continue")); - ClearEol(0, 7); - ClearEol(0, 8); - ClearEol(0, 9); - Flush(); + case kDown: DisplayMenu->SetItem(tr("Press 'Up' to confirm"), 3, false, false); + DisplayMenu->SetItem(tr("Press 'Down' to continue"), 4, false, false); + DisplayMenu->SetItem("", 5, false, false); + DisplayMenu->SetItem("", 6, false, false); + DisplayMenu->SetItem("", 7, false, false); + DisplayMenu->Flush(); for (;;) { Key = cRemote::Get(100); if (Key == kUp) { - Clear(); + DisplayMenu->Clear(); return true; } else if (Key == kDown) { - ClearEol(0, 6); + DisplayMenu->SetItem("", 4, false, false); k = kNone; // breaks the outer for() loop break; } @@ -394,17 +139,17 @@ bool cInterface::QueryKeys(cRemote *Remote) } } if (NewKey > kUp) - WriteText(1, 7, tr("(press 'Up' to go back)")); + DisplayMenu->SetItem(tr("(press 'Up' to go back)"), 5, false, false); else - ClearEol(0, 7); + DisplayMenu->SetItem("", 5, false, false); if (NewKey > kDown) - WriteText(1, 8, tr("(press 'Down' to end key definition)")); + DisplayMenu->SetItem(tr("(press 'Down' to end key definition)"), 6, false, false); else - ClearEol(0, 8); + DisplayMenu->SetItem("", 6, false, false); if (NewKey > kMenu) - WriteText(1, 9, tr("(press 'Menu' to skip this key)")); + DisplayMenu->SetItem(tr("(press 'Menu' to skip this key)"), 7, false, false); else - ClearEol(0, 9); + DisplayMenu->SetItem("", 7, false, false); } return true; } @@ -421,33 +166,31 @@ void cInterface::LearnKeys(void) bool known = Keys.KnowsRemote(Remote->Name()); dsyslog("remote control %s - %s", Remote->Name(), known ? "keys known" : "learning keys"); if (!known) { - Open(); - char Headline[Width()]; + cSkinDisplayMenu *DisplayMenu = Skins.Current()->DisplayMenu(); + char Headline[256]; snprintf(Headline, sizeof(Headline), tr("Learning Remote Control Keys (%s)"), Remote->Name()); - Clear(); cRemote::Clear(); - WriteText(1, 1, Headline); + DisplayMenu->SetTitle(Headline); cRemote::SetLearning(Remote); - bool rc = QueryKeys(Remote); + bool rc = QueryKeys(Remote, DisplayMenu); cRemote::SetLearning(NULL); - Clear(); + DisplayMenu->Clear(); if (!rc) { - Close(); + delete DisplayMenu; continue; } - WriteText(1, 1, Headline); - WriteText(1, 3, tr("Phase 3: Saving key codes")); - WriteText(1, 5, tr("Press 'Up' to save, 'Down' to cancel")); + DisplayMenu->SetItem(tr("Phase 3: Saving key codes"), 1, false, false); + DisplayMenu->SetItem(tr("Press 'Up' to save, 'Down' to cancel"), 3, false, false); for (;;) { eKeys key = GetKey(); if (key == kUp) { Keys.Save(); - Close(); + delete DisplayMenu; break; } else if (key == kDown) { Keys.Load(); - Close(); + delete DisplayMenu; break; } } |