summaryrefslogtreecommitdiff
path: root/osdbase.c
diff options
context:
space:
mode:
authorKlaus Schmidinger <kls (at) cadsoft (dot) de>2004-05-16 18:00:00 +0200
committerKlaus Schmidinger <kls (at) cadsoft (dot) de>2004-05-16 18:00:00 +0200
commitc80a53ff6ea22aa14d1f9772b310b77ea0da7c42 (patch)
treec2c6d9dc5c939765abc61fb0f19de00f988aecc9 /osdbase.c
parent9384e56566f56e77d577319a42929e708936e7c7 (diff)
downloadvdr-patch-lnbsharing-c80a53ff6ea22aa14d1f9772b310b77ea0da7c42.tar.gz
vdr-patch-lnbsharing-c80a53ff6ea22aa14d1f9772b310b77ea0da7c42.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 'osdbase.c')
-rw-r--r--osdbase.c667
1 files changed, 291 insertions, 376 deletions
diff --git a/osdbase.c b/osdbase.c
index 7179406..08aef96 100644
--- a/osdbase.c
+++ b/osdbase.c
@@ -4,495 +4,410 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: osdbase.c 1.12 2004/01/31 10:31:13 kls Exp $
+ * $Id: osdbase.c 1.13 2004/05/01 10:51:43 kls Exp $
*/
#include "osdbase.h"
-#include <signal.h>
-#include <stdlib.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/unistd.h>
-#include "tools.h"
+#include <string.h>
+#include "device.h"
+#include "i18n.h"
+#include "remote.h"
+#include "status.h"
-// --- cPalette --------------------------------------------------------------
+// --- cOsdItem --------------------------------------------------------------
-cPalette::cPalette(int Bpp)
+cOsdItem::cOsdItem(eOSState State)
{
- maxColors = 1 << Bpp;
- numColors = 0;
- full = false;
+ text = NULL;
+ offset = -1;
+ state = State;
+ selectable = true;
+ fresh = true;
}
-void cPalette::SetColor(int Index, eDvbColor Color)
+cOsdItem::cOsdItem(const char *Text, eOSState State)
{
- if (Index < maxColors) {
- if (numColors < Index)
- numColors = Index + 1;
- used[Index] = true;
- color[Index] = Color;
- fetched[Index] = false;
- }
+ text = NULL;
+ offset = -1;
+ state = State;
+ selectable = true;
+ fresh = true;
+ SetText(Text);
}
-int cPalette::Index(eDvbColor Color)
+cOsdItem::~cOsdItem()
{
-#if __BYTE_ORDER == __BIG_ENDIAN
- Color = eDvbColor(((Color & 0xFF) << 24) | ((Color & 0xFF00) << 8) | ((Color & 0xFF0000) >> 8) | ((Color & 0xFF000000) >> 24));
-#endif
- 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("ERROR: too many different colors used in palette");
- full = true;
- }
- return 0;
+ free(text);
}
-void cPalette::Reset(void)
+void cOsdItem::SetText(const char *Text, bool Copy)
{
- for (int i = 0; i < numColors; i++)
- used[i] = fetched[i] = false;
- full = false;
+ free(text);
+ text = Copy ? strdup(Text) : (char *)Text; // text assumes ownership!
}
-const eDvbColor *cPalette::NewColors(int &FirstColor, int &LastColor)
+void cOsdItem::SetSelectable(bool Selectable)
{
- 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;
+ selectable = Selectable;
}
-const eDvbColor *cPalette::AllColors(int &NumColors)
+void cOsdItem::SetFresh(bool Fresh)
{
- NumColors = numColors;
- return numColors ? color : NULL;
+ fresh = Fresh;
}
-void cPalette::Take(const cPalette &Palette, tIndexes *Indexes)
+eOSState cOsdItem::ProcessKey(eKeys Key)
{
- for (int i = 0; i < Palette.numColors; i++) {
- if (Palette.used[i]) {
- int n = Index(Palette.color[i]);
- if (Indexes)
- (*Indexes)[i] = n;
- }
- }
+ return Key == kOk ? state : osUnknown;
}
-// --- cBitmap ---------------------------------------------------------------
+// --- cOsdMenu --------------------------------------------------------------
-cBitmap::cBitmap(int Width, int Height, int Bpp, bool ClearWithBackground)
-:cPalette(Bpp)
-{
- width = Width;
- height = Height;
- clearWithBackground = ClearWithBackground;
- bitmap = NULL;
- fontType = fontOsd;
- font = NULL;
- if (width > 0 && height > 0) {
- bitmap = MALLOC(u_char, width * height);
- if (bitmap) {
- Clean();
- memset(bitmap, 0x00, width * height);
- SetFont(fontOsd);
- }
- else
- esyslog("ERROR: can't allocate bitmap!");
- }
- else
- esyslog("ERROR: illegal bitmap parameters (%d, %d)!", width, height);
-}
+cSkinDisplayMenu *cOsdMenu::displayMenu = NULL;
+int cOsdMenu::displayMenuCount = 0;
+int cOsdMenu::displayMenuItems = 0;//XXX dynamic???
-cBitmap::~cBitmap()
+cOsdMenu::cOsdMenu(const char *Title, int c0, int c1, int c2, int c3, int c4)
{
- free(bitmap);
-}
-
-eDvbFont cBitmap::SetFont(eDvbFont Font)
-{
- eDvbFont oldFont = fontType;
- if (fontType != Font || !font) {
- font = cFont::GetFont(Font);
- fontType = Font;
+ isMenu = true;
+ digit = 0;
+ hasHotkeys = false;
+ title = NULL;
+ SetTitle(Title);
+ cols[0] = c0;
+ cols[1] = c1;
+ cols[2] = c2;
+ cols[3] = c3;
+ cols[4] = c4;
+ first = 0;
+ current = marked = -1;
+ subMenu = NULL;
+ helpRed = helpGreen = helpYellow = helpBlue = NULL;
+ status = NULL;
+ if (!displayMenuCount++) {
+ displayMenu = Skins.Current()->DisplayMenu();
+ displayMenuItems = displayMenu->MaxItems();
}
- return oldFont;
}
-bool cBitmap::Dirty(int &x1, int &y1, int &x2, int &y2)
+cOsdMenu::~cOsdMenu()
{
- 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)
-{
- dirtyX1 = width;
- dirtyY1 = height;
- dirtyX2 = -1;
- dirtyY2 = -1;
+ free(title);
+ delete subMenu;
+ free(status);
+ displayMenu->Clear();
+ cStatus::MsgOsdClear();
+ if (!--displayMenuCount)
+ DELETENULL(displayMenu);
}
-void cBitmap::SetIndex(int x, int y, u_char Index)
+const char *cOsdMenu::hk(const char *s)
{
- if (bitmap) {
- if (0 <= x && x < width && 0 <= y && y < height) {
- 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;
- if (dirtyY2 < y) dirtyY2 = y;
- }
+ static char buffer[64];
+ if (s && hasHotkeys) {
+ if (digit == 0 && '1' <= *s && *s <= '9' && *(s + 1) == ' ')
+ digit = -1; // prevents automatic hotkeys - input already has them
+ if (digit >= 0) {
+ digit++;
+ snprintf(buffer, sizeof(buffer), " %c %s", (digit < 10) ? '0' + digit : ' ' , s);
+ s = buffer;
}
}
+ return s;
}
-void cBitmap::SetPixel(int x, int y, eDvbColor Color)
+void cOsdMenu::SetHasHotkeys(void)
{
- SetIndex(x, y, Index(Color));
+ hasHotkeys = true;
+ digit = 0;
}
-void cBitmap::SetBitmap(int x, int y, const cBitmap &Bitmap)
+void cOsdMenu::SetStatus(const char *s)
{
- 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++)
- SetIndex(x + ix, y + iy, Indexes[int(Bitmap.bitmap[Bitmap.width * iy + ix])]);
- }
- }
+ free(status);
+ status = s ? strdup(s) : NULL;
+ displayMenu->SetMessage(mtStatus, s);
}
-int cBitmap::Width(unsigned char c)
+void cOsdMenu::SetTitle(const char *Title)
{
- return font ? font->Width(c) : -1;
+ free(title);
+ title = strdup(Title);
}
-int cBitmap::Width(const char *s)
+void cOsdMenu::SetHelp(const char *Red, const char *Green, const char *Yellow, const char *Blue)
{
- return font ? font->Width(s) : -1;
+ // strings are NOT copied - must be constants!!!
+ helpRed = Red;
+ helpGreen = Green;
+ helpYellow = Yellow;
+ helpBlue = Blue;
+ displayMenu->SetButtons(helpRed, helpGreen, helpYellow, helpBlue);
+ cStatus::MsgOsdHelpKeys(helpRed, helpGreen, helpYellow, helpBlue);
}
-void cBitmap::Text(int x, int y, const char *s, eDvbColor ColorFg, eDvbColor ColorBg)
+void cOsdMenu::Del(int Index)
{
- if (bitmap) {
- u_char fg = Index(ColorFg);
- u_char bg = Index(ColorBg);
- int h = font->Height(s);
- while (s && *s) {
- const cFont::tCharData *CharData = font->CharData(*s++);
- if (int(x + CharData->width) > width)
- break;
- for (int row = 0; row < h; row++) {
- cFont::tPixelData PixelData = CharData->lines[row];
- for (int col = CharData->width; col-- > 0; ) {
- SetIndex(x + col, y + row, (PixelData & 1) ? fg : bg);
- PixelData >>= 1;
- }
- }
- x += CharData->width;
- }
- }
+ cList<cOsdItem>::Del(Get(Index));
+ if (current == Count())
+ current--;
+ if (Index == first && first > 0)
+ first--;
}
-void cBitmap::Fill(int x1, int y1, int x2, int y2, eDvbColor Color)
-{
- if (bitmap) {
- u_char c = Index(Color);
- for (int y = y1; y <= y2; y++)
- for (int x = x1; x <= x2; x++)
- SetIndex(x, y, c);
- }
-}
-
-void cBitmap::Clear(void)
-{
- Reset();
- if (clearWithBackground)
- Fill(0, 0, width - 1, height - 1, clrBackground);
-}
-
-const u_char *cBitmap::Data(int x, int y)
-{
- return &bitmap[y * width + x];
-}
-
-// --- cWindow ---------------------------------------------------------------
-
-cWindow::cWindow(int Handle, int x, int y, int w, int h, int Bpp, bool ClearWithBackground, bool Tiled)
-:cBitmap(w, h, Bpp, ClearWithBackground)
+void cOsdMenu::Add(cOsdItem *Item, bool Current, cOsdItem *After)
{
- handle = Handle;
- x0 = x;
- y0 = y;
- bpp = Bpp;
- tiled = Tiled;
- shown = false;
+ cList<cOsdItem>::Add(Item, After);
+ if (Current)
+ current = Item->Index();
}
-bool cWindow::Contains(int x, int y)
+void cOsdMenu::Ins(cOsdItem *Item, bool Current, cOsdItem *Before)
{
- x -= x0;
- y -= y0;
- return x >= 0 && y >= 0 && x < width && y < height;
+ cList<cOsdItem>::Ins(Item, Before);
+ if (Current)
+ current = Item->Index();
}
-void cWindow::Relocate(int x, int y)
+void cOsdMenu::Display(void)
{
- x0 = x;
- y0 = y;
+ if (subMenu) {
+ subMenu->Display();
+ return;
+ }
+ displayMenu->Clear();
+ cStatus::MsgOsdClear();
+ displayMenu->SetTabs(cols[0], cols[1], cols[2], cols[3], cols[4]);//XXX
+ displayMenu->SetTitle(title);
+ cStatus::MsgOsdTitle(title);
+ displayMenu->SetButtons(helpRed, helpGreen, helpYellow, helpBlue);
+ cStatus::MsgOsdHelpKeys(helpRed, helpGreen, helpYellow, helpBlue);
+ int count = Count();
+ if (count > 0) {
+ int ni = 0;
+ for (cOsdItem *item = First(); item; item = Next(item))
+ cStatus::MsgOsdItem(item->Text(), ni++);
+ if (current < 0)
+ current = 0; // just for safety - there HAS to be a current item!
+ if (current - first >= displayMenuItems || current < first) {
+ first = current - displayMenuItems / 2;
+ if (first + displayMenuItems > count)
+ first = count - displayMenuItems;
+ if (first < 0)
+ first = 0;
+ }
+ int i = first;
+ int n = 0;
+ for (cOsdItem *item = Get(first); item; item = Next(item)) {
+ displayMenu->SetItem(item->Text(), i - first, i == current, item->Selectable());
+ if (i == current)
+ cStatus::MsgOsdCurrentItem(item->Text());
+ if (++n == displayMenuItems)
+ break;
+ i++;
+ }
+ }
+ if (!isempty(status))
+ displayMenu->SetMessage(mtStatus, status);
}
-void cWindow::Fill(int x1, int y1, int x2, int y2, eDvbColor Color)
+void cOsdMenu::SetCurrent(cOsdItem *Item)
{
- if (tiled) {
- x1 -= x0;
- y1 -= y0;
- x2 -= x0;
- y2 -= y0;
- }
- cBitmap::Fill(x1, y1, x2, y2, Color);
+ current = Item ? Item->Index() : -1;
}
-void cWindow::SetBitmap(int x, int y, const cBitmap &Bitmap)
+void cOsdMenu::RefreshCurrent(void)
{
- if (tiled) {
- x -= x0;
- y -= y0;
- }
- cBitmap::SetBitmap(x, y, Bitmap);
+ cOsdItem *item = Get(current);
+ if (item)
+ item->Set();
}
-void cWindow::Text(int x, int y, const char *s, eDvbColor ColorFg, eDvbColor ColorBg)
+void cOsdMenu::DisplayCurrent(bool Current)
{
- if (tiled) {
- x -= x0;
- y -= y0;
+ cOsdItem *item = Get(current);
+ if (item) {
+ displayMenu->SetItem(item->Text(), current - first, Current, item->Selectable());
+ if (Current)
+ cStatus::MsgOsdCurrentItem(item->Text());
+ if (!Current)
+ item->SetFresh(true); // leaving the current item resets 'fresh'
}
- cBitmap::Text(x, y, s, ColorFg, ColorBg);
}
-const u_char *cWindow::Data(int x, int y)
+void cOsdMenu::Clear(void)
{
- return cBitmap::Data(x, y);
+ first = 0;
+ current = marked = -1;
+ cList<cOsdItem>::Clear();
}
-// --- cOsdBase --------------------------------------------------------------
-
-cOsdBase::cOsdBase(int x, int y)
+bool cOsdMenu::SelectableItem(int idx)
{
- numWindows = 0;
- x0 = x;
- y0 = y;
+ cOsdItem *item = Get(idx);
+ return item && item->Selectable();
}
-cOsdBase::~cOsdBase()
+void cOsdMenu::CursorUp(void)
{
- for (int i = 0; i < numWindows; i++)
- delete window[i];
+ if (current > 0) {
+ int tmpCurrent = current;
+ while (--tmpCurrent >= 0 && !SelectableItem(tmpCurrent));
+ if (tmpCurrent < 0)
+ return;
+ if (tmpCurrent >= first)
+ DisplayCurrent(false);
+ current = tmpCurrent;
+ if (current < first) {
+ first = first > displayMenuItems - 1 ? first - (displayMenuItems - 1) : 0;
+ if (Setup.MenuScrollPage)
+ current = !SelectableItem(first) ? first + 1 : first;
+ Display();
+ }
+ else
+ DisplayCurrent(true);
+ }
}
-tWindowHandle cOsdBase::Create(int x, int y, int w, int h, int Bpp, bool ClearWithBackground, bool Tiled)
-{
- 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);
- dsyslog("OSD window width must be a multiple of 4 - increasing to %d", w);
+void cOsdMenu::CursorDown(void)
+{
+ int last = Count() - 1;
+ int lastOnScreen = first + displayMenuItems - 1;
+
+ if (current < last) {
+ int tmpCurrent = current;
+ while (++tmpCurrent <= last && !SelectableItem(tmpCurrent));
+ if (tmpCurrent > last)
+ return;
+ if (tmpCurrent <= lastOnScreen)
+ DisplayCurrent(false);
+ current = tmpCurrent;
+ if (current > lastOnScreen) {
+ first += displayMenuItems - 1;
+ lastOnScreen = first + displayMenuItems - 1;
+ if (lastOnScreen > last) {
+ first = last - (displayMenuItems - 1);
+ lastOnScreen = last;
}
- cWindow *win = new cWindow(numWindows, x, y, w, h, Bpp, ClearWithBackground, Tiled);
- if (OpenWindow(win)) {
- window[win->Handle()] = win;
- numWindows++;
- return win->Handle();
- }
- else
- delete win;
+ if (Setup.MenuScrollPage)
+ current = !SelectableItem(lastOnScreen) ? lastOnScreen - 1 : lastOnScreen;
+ Display();
}
else
- esyslog("ERROR: illegal OSD parameters");
+ DisplayCurrent(true);
}
- else
- esyslog("ERROR: too many OSD windows");
- return -1;
}
-void cOsdBase::AddColor(eDvbColor Color, tWindowHandle Window)
+void cOsdMenu::PageUp(void)
{
- cWindow *w = GetWindow(Window);
- if (w) {
- w->Index(Color);
- w->Reset();
+ current -= displayMenuItems;
+ first -= displayMenuItems;
+ if (first < 0)
+ first = current = 0;
+ if (!SelectableItem(current)) {
+ current -= (current > 0) ? 1 : -1;
+ first = min(first, current - 1);
}
+ Display();
+ DisplayCurrent(true);
}
-cWindow *cOsdBase::GetWindow(int x, int y)
-{
- for (int i = 0; i < numWindows; i++) {
- if (window[i]->Tiled() && window[i]->Contains(x, y))
- return window[i];
- }
- return NULL;
-}
-
-cWindow *cOsdBase::GetWindow(tWindowHandle Window)
-{
- if (0 <= Window && Window < numWindows)
- return window[Window];
- if (Window == LAST_CREATED_WINDOW && numWindows > 0)
- return window[numWindows - 1];
- return NULL;
-}
-
-void cOsdBase::Flush(void)
-{
- for (int i = 0; i < numWindows; i++) {
- CommitWindow(window[i]);
- 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())
- ShowWindow(window[i]);
- }
-}
-
-void cOsdBase::Clear(tWindowHandle Window)
+void cOsdMenu::PageDown(void)
{
- if (Window == ALL_TILED_WINDOWS || Window == ALL_WINDOWS) {
- for (int i = 0; i < numWindows; i++)
- if (Window == ALL_WINDOWS || window[i]->Tiled())
- window[i]->Clear();
+ current += displayMenuItems;
+ first += displayMenuItems;
+ int count = Count();
+ if (current > count - 1) {
+ current = count - 1;
+ first = max(0, count - displayMenuItems);
}
- else {
- cWindow *w = GetWindow(Window);
- if (w)
- w->Clear();
+ if (!SelectableItem(current)) {
+ current += (current < count - 1) ? 1 : -1;
+ first = max(first, current - displayMenuItems);
}
+ Display();
+ DisplayCurrent(true);
}
-void cOsdBase::Fill(int x1, int y1, int x2, int y2, eDvbColor Color, tWindowHandle Window)
-{
- cWindow *w = (Window == ALL_TILED_WINDOWS) ? GetWindow(x1, y1) : GetWindow(Window);
- if (w)
- w->Fill(x1, y1, x2, y2, Color);
-}
-
-void cOsdBase::SetBitmap(int x, int y, const cBitmap &Bitmap, tWindowHandle Window)
+void cOsdMenu::Mark(void)
{
- cWindow *w = (Window == ALL_TILED_WINDOWS) ? GetWindow(x, y) : GetWindow(Window);
- if (w)
- w->SetBitmap(x, y, Bitmap);
+ if (Count() && marked < 0) {
+ marked = current;
+ SetStatus(tr("Up/Dn for new location - OK to move"));
+ }
}
-int cOsdBase::Width(unsigned char c)
+eOSState cOsdMenu::HotKey(eKeys Key)
{
- return numWindows ? window[0]->Width(c) : 0;
+ for (cOsdItem *item = First(); item; item = Next(item)) {
+ const char *s = item->Text();
+ if (s && (s = skipspace(s)) != NULL) {
+ if (*s == Key - k1 + '1') {
+ current = item->Index();
+ cRemote::Put(kOk, true);
+ break;
+ }
+ }
+ }
+ return osContinue;
}
-int cOsdBase::Width(const char *s)
+eOSState cOsdMenu::AddSubMenu(cOsdMenu *SubMenu)
{
- return numWindows ? window[0]->Width(s) : 0;
+ delete subMenu;
+ subMenu = SubMenu;
+ subMenu->Display();
+ return osContinue; // convenience return value
}
-eDvbFont cOsdBase::SetFont(eDvbFont Font)
+eOSState cOsdMenu::CloseSubMenu()
{
- eDvbFont oldFont = Font;
- for (int i = 0; i < numWindows; i++)
- oldFont = window[i]->SetFont(Font);
- return oldFont;
+ delete subMenu;
+ subMenu = NULL;
+ RefreshCurrent();
+ Display();
+ return osContinue; // convenience return value
}
-void cOsdBase::Text(int x, int y, const char *s, eDvbColor ColorFg, eDvbColor ColorBg, tWindowHandle Window)
+eOSState cOsdMenu::ProcessKey(eKeys Key)
{
- cWindow *w = (Window == ALL_TILED_WINDOWS) ? GetWindow(x, y) : GetWindow(Window);
- if (w)
- w->Text(x, y, s, ColorFg, ColorBg);
-}
+ if (subMenu) {
+ eOSState state = subMenu->ProcessKey(Key);
+ if (state == osBack)
+ return CloseSubMenu();
+ return state;
+ }
-void cOsdBase::Relocate(tWindowHandle Window, int x, int y, int NewWidth, int NewHeight)
-{
- cWindow *w = GetWindow(Window);
- if (w) {
- if (NewWidth > 0 && NewHeight > 0) {
- if ((NewWidth & 0x03) != 0) {
- NewWidth += 4 - (NewWidth & 0x03);
- dsyslog("OSD window width must be a multiple of 4 - increasing to %d", NewWidth);
- }
- CloseWindow(w);
- cWindow *NewWindow = new cWindow(w->Handle(), x, y, NewWidth, NewHeight, w->Bpp(), w->ClearWithBackground(), w->Tiled());
- window[w->Handle()] = NewWindow;
- delete w;
- OpenWindow(NewWindow);
- }
- else {
- MoveWindow(w, x, y);
- w->Relocate(x, y);
+ cOsdItem *item = Get(current);
+ if (marked < 0 && item) {
+ eOSState state = item->ProcessKey(Key);
+ if (state != osUnknown) {
+ DisplayCurrent(true);
+ return state;
}
}
+ switch (Key) {
+ case k1...k9: return hasHotkeys ? HotKey(Key) : osUnknown;
+ case kUp|k_Repeat:
+ case kUp: CursorUp(); break;
+ case kDown|k_Repeat:
+ case kDown: CursorDown(); break;
+ case kLeft|k_Repeat:
+ case kLeft: PageUp(); break;
+ case kRight|k_Repeat:
+ case kRight: PageDown(); break;
+ case kBack: return osBack;
+ case kOk: if (marked >= 0) {
+ SetStatus(NULL);
+ if (marked != current)
+ Move(marked, current);
+ marked = -1;
+ break;
+ }
+ // else run into default
+ default: if (marked < 0)
+ return osUnknown;
+ }
+ return osContinue;
}
-void cOsdBase::Hide(tWindowHandle Window)
-{
- HideWindow(GetWindow(Window), true);
-}
-
-void cOsdBase::Show(tWindowHandle Window)
-{
- HideWindow(GetWindow(Window), false);
-}