mirror of
				https://github.com/vdr-projects/vdr.git
				synced 2025-03-01 10:50:46 +00:00 
			
		
		
		
	Larger OSD with 2bpp windows; Channel display at bottom
This commit is contained in:
		
							
								
								
									
										6
									
								
								HISTORY
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								HISTORY
									
									
									
									
									
								
							| @@ -534,7 +534,7 @@ Video Disk Recorder Revision History | ||||
| - No longer getting stuck when a channel doesn't sync while switching | ||||
|   with the 'Up' and 'Down' keys. | ||||
|  | ||||
| 2001-07-21: Version 0.84 | ||||
| 2001-07-22: Version 0.84 | ||||
|  | ||||
| - Fixed video packet scanning to make it recognize the whole range of | ||||
|   allowed video packet ids. | ||||
| @@ -555,3 +555,7 @@ Video Disk Recorder Revision History | ||||
| - Increased the frame buffer size to 192KB. | ||||
| - Removed a superfluous VIDEO_FREEZE call in the replay buffer. | ||||
| - Added French language texts (thanks to Jean-Claude Repetto). | ||||
| - Modified OSD to use 2bpp windows (4 colors) in order to work with less | ||||
|   memory, allow a larger OSD window and be faster. The group separators in the | ||||
|   "Channels" menu had to be given a different color. | ||||
| - Moved the channel display to the bottom of the screen. | ||||
|   | ||||
							
								
								
									
										61
									
								
								dvbapi.c
									
									
									
									
									
								
							
							
						
						
									
										61
									
								
								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.86 2001/07/22 09:34:55 kls Exp $ | ||||
|  * $Id: dvbapi.c 1.87 2001/07/22 12:18:29 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "dvbapi.h" | ||||
| @@ -1843,25 +1843,6 @@ void cDvbApi::SetColor(eDvbColor colorFg, eDvbColor colorBg) | ||||
|          } | ||||
|       } | ||||
| } | ||||
| #else | ||||
| void cDvbApi::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1, const void *data) | ||||
| { | ||||
|   if (fd_osd >= 0) { | ||||
|      osd_cmd_t dc; | ||||
|      dc.cmd   = cmd; | ||||
|      dc.color = color; | ||||
|      dc.x0    = x0; | ||||
|      dc.y0    = y0; | ||||
|      dc.x1    = x1; | ||||
|      dc.y1    = y1; | ||||
|      dc.data  = (void *)data; | ||||
|      CHECK(ioctl(fd_osd, OSD_SEND_CMD, &dc)); | ||||
|      usleep(10); // XXX Workaround for a driver bug (cInterface::DisplayChannel() displayed texts at wrong places | ||||
|                  // XXX and sometimes the OSD was no longer displayed). | ||||
|                  // XXX Increase the value if the problem still persists on your particular system. | ||||
|                  // TODO Check if this is still necessary with driver versions after 0.6. | ||||
|      } | ||||
| } | ||||
| #endif | ||||
|  | ||||
| void cDvbApi::Open(int w, int h) | ||||
| @@ -1875,16 +1856,7 @@ void cDvbApi::Open(int w, int h) | ||||
|   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)) | ||||
| #else | ||||
|   w *= charWidth; | ||||
|   h *= lineHeight; | ||||
|   d *= lineHeight; | ||||
|   int x = (720 - MenuColumns * charWidth) / 2; //TODO PAL vs. NTSC??? | ||||
|   int y = (576 - MenuLines * lineHeight) / 2 + d; | ||||
|   osd = new cDvbOsd(fd_osd, x, y, x + w - 1, y + h - 1, 4); | ||||
|   #define SETCOLOR(n, r, g, b, o) Cmd(OSD_SetColor, n, r, g, b, o) | ||||
|   SETCOLOR(clrTransparent, 0x00, 0x00, 0x00,   0); | ||||
| #endif | ||||
|   //XXX | ||||
|   SETCOLOR(clrBackground,  0x00, 0x00, 0x00, 127); // background 50% gray | ||||
|   SETCOLOR(clrBlack,       0x00, 0x00, 0x00, 255); | ||||
|   SETCOLOR(clrRed,         0xFC, 0x14, 0x14, 255); | ||||
| @@ -1894,6 +1866,35 @@ void cDvbApi::Open(int w, int h) | ||||
|   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 - (MenuColumns - 1) * charWidth) / 2; //TODO PAL vs. NTSC??? | ||||
|   int y = (576 - MenuLines * 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 (d == 0) { //XXX full menu | ||||
|      osd->Create(0,                            0, w,                   lineHeight, 2); | ||||
|      osd->Create(0,                   lineHeight, w, (MenuLines - 3) * lineHeight, 2, true, clrBackground, clrCyan, clrWhite, clrBlack); | ||||
|      osd->Create(0, (MenuLines - 2) * lineHeight, w,               2 * lineHeight, 4); | ||||
|      } | ||||
|   else 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 { //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) | ||||
|   | ||||
							
								
								
									
										7
									
								
								dvbapi.h
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								dvbapi.h
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: dvbapi.h 1.40 2001/06/24 17:42:19 kls Exp $ | ||||
|  * $Id: dvbapi.h 1.41 2001/07/22 11:48:15 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef __DVBAPI_H | ||||
| @@ -36,8 +36,8 @@ typedef struct CRect { | ||||
|   signed short x, y, width, height; | ||||
|   }; | ||||
|  | ||||
| #define MenuLines   13 // XXX originally 15, but since driver version 2001-05-25 there is less OSD memory :-( | ||||
| #define MenuColumns 40 | ||||
| #define MenuLines   18 | ||||
| #define MenuColumns 52 | ||||
|  | ||||
| const char *IndexToHMSF(int Index, bool WithFrame = false); | ||||
|       // Converts the given index to a string, optionally containing the frame number. | ||||
| @@ -159,7 +159,6 @@ private: | ||||
|   cDvbOsd *osd; | ||||
| #endif | ||||
|   int cols, rows; | ||||
|   void Cmd(OSD_Command cmd, int color = 0, int x0 = 0, int y0 = 0, int x1 = 0, int y1 = 0, const void *data = NULL); | ||||
| public: | ||||
|   void Open(int w, int h); | ||||
|   void Close(void); | ||||
|   | ||||
							
								
								
									
										340
									
								
								dvbosd.c
									
									
									
									
									
								
							
							
						
						
									
										340
									
								
								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.8 2001/05/26 11:49:35 kls Exp $ | ||||
|  * $Id: dvbosd.c 1.9 2001/07/22 11:48:54 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "dvbosd.h" | ||||
| @@ -14,12 +14,83 @@ | ||||
| #include <sys/unistd.h> | ||||
| #include "tools.h" | ||||
|  | ||||
| // --- cPalette -------------------------------------------------------------- | ||||
|  | ||||
| cPalette::cPalette(int Bpp) | ||||
| { | ||||
|   maxColors = 1 << Bpp; | ||||
|   numColors = 0; | ||||
|   full = false; | ||||
| } | ||||
|  | ||||
| int cPalette::Index(eDvbColor Color) | ||||
| { | ||||
|   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(LOG_ERR, "ERROR: too many different colors used in palette"); | ||||
|      full = true; | ||||
|      } | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| void cPalette::Reset(void) | ||||
| { | ||||
|   for (int i = 0; i < numColors; i++) | ||||
|       used[i] = false; | ||||
|   full = false; | ||||
| } | ||||
|  | ||||
| const eDvbColor *cPalette::Colors(int &FirstColor, int &LastColor) | ||||
| { | ||||
|   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; | ||||
| } | ||||
|  | ||||
| void cPalette::Take(const cPalette &Palette, tIndexes *Indexes) | ||||
| { | ||||
|   for (int i = 0; i < Palette.numColors; i++) { | ||||
|       if (Palette.used[i]) { | ||||
|          int n = Index(Palette.color[i]); | ||||
|          if (Indexes) | ||||
|             (*Indexes)[i] = n; | ||||
|          } | ||||
|       } | ||||
| } | ||||
|  | ||||
| // --- cBitmap --------------------------------------------------------------- | ||||
|  | ||||
| cBitmap::cBitmap(int Width, int Height) | ||||
| cBitmap::cBitmap(int Width, int Height, int Bpp, bool ClearWithBackground) | ||||
| :cPalette(Bpp) | ||||
| { | ||||
|   width = Width; | ||||
|   height = Height; | ||||
|   clearWithBackground = ClearWithBackground; | ||||
|   bitmap = NULL; | ||||
|   fontType = fontOsd; | ||||
|   font = NULL; | ||||
| @@ -27,7 +98,7 @@ cBitmap::cBitmap(int Width, int Height) | ||||
|      bitmap = new char[width * height]; | ||||
|      if (bitmap) { | ||||
|         Clean(); | ||||
|         memset(bitmap, clrTransparent, width * height); | ||||
|         memset(bitmap, 0x00, width * height); | ||||
|         SetFont(fontOsd); | ||||
|         } | ||||
|      else | ||||
| @@ -54,9 +125,38 @@ eDvbFont cBitmap::SetFont(eDvbFont Font) | ||||
|   return oldFont; | ||||
| } | ||||
|  | ||||
| bool cBitmap::Dirty(void) | ||||
| bool cBitmap::Dirty(int &x1, int &y1, int &x2, int &y2) | ||||
| { | ||||
|   return dirtyX2 >= 0; | ||||
|   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) | ||||
| @@ -67,12 +167,12 @@ void cBitmap::Clean(void) | ||||
|   dirtyY2 = -1; | ||||
| } | ||||
|  | ||||
| void cBitmap::SetPixel(int x, int y, eDvbColor Color) | ||||
| void cBitmap::SetIndex(int x, int y, char Index) | ||||
| { | ||||
|   if (bitmap) { | ||||
|      if (0 <= x && x < width && 0 <= y && y < height) { | ||||
|         if (bitmap[width * y + x] != Color) { | ||||
|            bitmap[width * y + x] = Color; | ||||
|         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; | ||||
| @@ -82,12 +182,19 @@ void cBitmap::SetPixel(int x, int y, eDvbColor Color) | ||||
|      } | ||||
| } | ||||
|  | ||||
| void cBitmap::SetPixel(int x, int y, eDvbColor Color) | ||||
| { | ||||
|   SetIndex(x, y, Index(Color)); | ||||
| } | ||||
|  | ||||
| void cBitmap::SetBitmap(int x, int y, const cBitmap &Bitmap) | ||||
| { | ||||
|   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++) | ||||
|              SetPixel(x + ix, y + iy, eDvbColor(Bitmap.bitmap[Bitmap.width * iy + ix])); | ||||
|              SetIndex(x + ix, y + iy, Indexes[Bitmap.bitmap[Bitmap.width * iy + ix]]); | ||||
|          } | ||||
|      } | ||||
| } | ||||
| @@ -105,6 +212,8 @@ int cBitmap::Width(const char *s) | ||||
| void cBitmap::Text(int x, int y, const char *s, eDvbColor ColorFg, eDvbColor ColorBg) | ||||
| { | ||||
|   if (bitmap) { | ||||
|      char fg = Index(ColorFg); | ||||
|      char bg = Index(ColorBg); | ||||
|      int h = font->Height(s); | ||||
|      while (s && *s) { | ||||
|            const cFont::tCharData *CharData = font->CharData(*s++); | ||||
| @@ -113,7 +222,7 @@ void cBitmap::Text(int x, int y, const char *s, eDvbColor ColorFg, eDvbColor Col | ||||
|            for (int row = 0; row < h; row++) { | ||||
|                cFont::tPixelData PixelData = CharData->lines[row]; | ||||
|                for (int col = CharData->width; col-- > 0; ) { | ||||
|                    SetPixel(x + col, y + row, (PixelData & 1) ? ColorFg : ColorBg); | ||||
|                    SetIndex(x + col, y + row, (PixelData & 1) ? fg : bg); | ||||
|                    PixelData >>= 1; | ||||
|                    } | ||||
|                } | ||||
| @@ -125,33 +234,103 @@ void cBitmap::Text(int x, int y, const char *s, eDvbColor ColorFg, eDvbColor Col | ||||
| void cBitmap::Fill(int x1, int y1, int x2, int y2, eDvbColor Color) | ||||
| { | ||||
|   if (bitmap) { | ||||
|      char c = Index(Color); | ||||
|      for (int y = y1; y <= y2; y++) | ||||
|          for (int x = x1; x <= x2; x++) | ||||
|              SetPixel(x, y, Color); | ||||
|              SetIndex(x, y, c); | ||||
|      } | ||||
| } | ||||
|  | ||||
| void cBitmap::Clear(void) | ||||
| { | ||||
|   Fill(0, 0, width - 1, height - 1, clrBackground); | ||||
|   Reset(); | ||||
|   if (clearWithBackground) | ||||
|      Fill(0, 0, width - 1, height - 1, clrBackground); | ||||
| } | ||||
|  | ||||
| const char *cBitmap::Data(int x, int y) | ||||
| { | ||||
|   return &bitmap[y * width + x]; | ||||
| } | ||||
|  | ||||
| // --- cWindow --------------------------------------------------------------- | ||||
|  | ||||
| class cWindow : public cBitmap { | ||||
| private: | ||||
|   int x0, y0; | ||||
|   bool shown; | ||||
| public: | ||||
|   cWindow(int x, int y, int w, int h, int Bpp, bool ClearWithBackground = true); | ||||
|   int X0(void) { return x0; } | ||||
|   int Y0(void) { return y0; } | ||||
|   bool Shown(void) { bool s = shown; shown = true; return s; } | ||||
|   bool Contains(int x, int y); | ||||
|   void Fill(int x1, int y1, int x2, int y2, eDvbColor Color); | ||||
|   void SetBitmap(int x, int y, const cBitmap &Bitmap); | ||||
|   void Text(int x, int y, const char *s, eDvbColor ColorFg = clrWhite, eDvbColor ColorBg = clrBackground); | ||||
|   const char *Data(int x, int y); | ||||
|   }; | ||||
|  | ||||
| cWindow::cWindow(int x, int y, int w, int h, int Bpp, bool ClearWithBackground) | ||||
| :cBitmap(w, h, Bpp, ClearWithBackground) | ||||
| { | ||||
|   x0 = x; | ||||
|   y0 = y; | ||||
|   shown = false; | ||||
| } | ||||
|  | ||||
| bool cWindow::Contains(int x, int y) | ||||
| { | ||||
|   x -= x0; | ||||
|   y -= y0; | ||||
|   return x >= 0 && y >= 0 && x < width && y < height; | ||||
| } | ||||
|  | ||||
| void cWindow::Fill(int x1, int y1, int x2, int y2, eDvbColor Color) | ||||
| { | ||||
|   cBitmap::Fill(x1 - x0, y1 - y0, x2 - x0, y2 - y0, Color); | ||||
| } | ||||
|  | ||||
| void cWindow::SetBitmap(int x, int y, const cBitmap &Bitmap) | ||||
| { | ||||
|   cBitmap::SetBitmap(x - x0, y - y0, Bitmap); | ||||
| } | ||||
|  | ||||
| void cWindow::Text(int x, int y, const char *s, eDvbColor ColorFg, eDvbColor ColorBg) | ||||
| { | ||||
|   cBitmap::Text(x - x0, y - y0, s, ColorFg, ColorBg); | ||||
| } | ||||
|  | ||||
| const char *cWindow::Data(int x, int y) | ||||
| { | ||||
|   return cBitmap::Data(x, y); | ||||
| } | ||||
|  | ||||
| // --- cDvbOsd --------------------------------------------------------------- | ||||
|  | ||||
| cDvbOsd::cDvbOsd(int VideoDev, int x1, int y1, int x2, int y2, int Bpp) | ||||
| :cBitmap(x2 - x1 + 1, y2 - y1 + 1) | ||||
| cDvbOsd::cDvbOsd(int VideoDev, int x, int y, int w, int h, int Bpp) | ||||
| { | ||||
|   videoDev = VideoDev; | ||||
|   if (videoDev >= 0) | ||||
|      Cmd(OSD_Open, Bpp, x1, y1, x2, y2); | ||||
|   numWindows = 0; | ||||
|   x0 = x; | ||||
|   y0 = y; | ||||
|   if (videoDev >= 0) { | ||||
|      if (w > 0 && h > 0) | ||||
|         Create(0, 0, w, h, Bpp); | ||||
|      } | ||||
|   else | ||||
|      esyslog(LOG_ERR, "ERROR: illegal video device handle (%d)!", videoDev); | ||||
| } | ||||
|  | ||||
| cDvbOsd::~cDvbOsd() | ||||
| { | ||||
|   if (videoDev >= 0) | ||||
|      Cmd(OSD_Close); | ||||
|   if (videoDev >= 0) { | ||||
|      while (numWindows > 0) { | ||||
|            Cmd(OSD_SetWindow, 0, numWindows--); | ||||
|            Cmd(OSD_Close); | ||||
|            delete window[numWindows]; | ||||
|            } | ||||
|      } | ||||
| } | ||||
|  | ||||
| void cDvbOsd::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1, const void *data) | ||||
| @@ -178,32 +357,111 @@ void cDvbOsd::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1, co | ||||
|      } | ||||
| } | ||||
|  | ||||
| void cDvbOsd::Flush(void) | ||||
| bool cDvbOsd::Create(int x, int y, int w, int h, int Bpp, bool ClearWithBackground, eDvbColor Color0, eDvbColor Color1, eDvbColor Color2, eDvbColor Color3) | ||||
| { | ||||
|   if (Dirty()) { | ||||
|      //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--; | ||||
|   /* TODO XXX | ||||
|      - check that no two windows overlap | ||||
|   */ | ||||
|   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); | ||||
|            esyslog(LOG_ERR, "ERROR: OSD window width must be a multiple of 4 - increasing to %d", w); | ||||
|            } | ||||
|      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--; | ||||
|         cWindow *win = new cWindow(x, y, w, h, Bpp, ClearWithBackground); | ||||
|         if (Color0 != clrTransparent) { | ||||
|            win->Index(Color0); | ||||
|            win->Index(Color1); | ||||
|            win->Index(Color2); | ||||
|            win->Index(Color3); | ||||
|            win->Reset(); | ||||
|            } | ||||
|      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--; | ||||
|            } | ||||
|      Cmd(OSD_SetBlock, width, dirtyX1, dirtyY1, dirtyX2, dirtyY2, &bitmap[dirtyY1 * width + dirtyX1]); | ||||
|      Clean(); | ||||
|         window[numWindows++] = win; | ||||
|         Cmd(OSD_SetWindow, 0, numWindows); | ||||
|         Cmd(OSD_Open, Bpp, x0 + x, y0 + y, x0 + x + w - 1, y0 + y + h - 1, (void *)1); // initially hidden! | ||||
|         } | ||||
|      else | ||||
|         esyslog(LOG_ERR, "ERROR: illegal OSD parameters"); | ||||
|      } | ||||
|   else | ||||
|      esyslog(LOG_ERR, "ERROR: too many OSD windows"); | ||||
|   return false; | ||||
| } | ||||
|  | ||||
| cWindow *cDvbOsd::GetWindow(int x, int y) | ||||
| { | ||||
|   for (int i = 0; i < numWindows; i++) { | ||||
|       if (window[i]->Contains(x, y)) | ||||
|          return window[i]; | ||||
|       } | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| void cDvbOsd::Flush(void) | ||||
| { | ||||
|   for (int i = 0; i < numWindows; i++) { | ||||
|       int x1 = 0, y1 = 0, x2 = 0, y2 = 0; | ||||
|       if (window[i]->Dirty(x1, y1, x2, y2)) { | ||||
|          Cmd(OSD_SetWindow, 0, i + 1); | ||||
|          int FirstColor = 0, LastColor = 0; | ||||
|          const eDvbColor *pal; | ||||
|          while ((pal = window[i]->Colors(FirstColor, LastColor)) != NULL) | ||||
|                Cmd(OSD_SetPalette, FirstColor, LastColor, 0, 0, 0, pal); | ||||
|          Cmd(OSD_SetBlock, window[i]->Width(), x1, y1, x2, y2, window[i]->Data(x1, y1)); | ||||
|          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()) { | ||||
|          Cmd(OSD_SetWindow, 0, i + 1); | ||||
|          Cmd(OSD_MoveWindow, 0, x0 + window[i]->X0(), y0 + window[i]->Y0()); | ||||
|          } | ||||
|       } | ||||
| } | ||||
|  | ||||
| void cDvbOsd::Clear(void) | ||||
| { | ||||
|   for (int i = 0; i < numWindows; i++) | ||||
|       window[i]->Clear(); | ||||
| } | ||||
|  | ||||
| void cDvbOsd::Fill(int x1, int y1, int x2, int y2, eDvbColor Color) | ||||
| { | ||||
|   cWindow *w = GetWindow(x1, y1); | ||||
|   if (w) | ||||
|      w->Fill(x1, y1, x2, y2, Color); | ||||
| } | ||||
|  | ||||
| void cDvbOsd::SetBitmap(int x, int y, const cBitmap &Bitmap) | ||||
| { | ||||
|   cWindow *w = GetWindow(x, y); | ||||
|   if (w) | ||||
|      w->SetBitmap(x, y, Bitmap); | ||||
| } | ||||
|  | ||||
| int cDvbOsd::Width(unsigned char c) | ||||
| { | ||||
|   return numWindows ? window[0]->Width(c) : 0; | ||||
| } | ||||
|  | ||||
| int cDvbOsd::Width(const char *s) | ||||
| { | ||||
|   return numWindows ? window[0]->Width(s) : 0; | ||||
| } | ||||
|  | ||||
| eDvbFont cDvbOsd::SetFont(eDvbFont Font) | ||||
| { | ||||
|   eDvbFont oldFont = Font; | ||||
|   for (int i = 0; i < numWindows; i++) | ||||
|       oldFont = window[i]->SetFont(Font); | ||||
|   return oldFont; | ||||
| } | ||||
|  | ||||
| void cDvbOsd::Text(int x, int y, const char *s, eDvbColor ColorFg = clrWhite, eDvbColor ColorBg = clrBackground) | ||||
| { | ||||
|   cWindow *w = GetWindow(x, y); | ||||
|   if (w) | ||||
|      w->Text(x, y, s, ColorFg, ColorBg); | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										80
									
								
								dvbosd.h
									
									
									
									
									
								
							
							
						
						
									
										80
									
								
								dvbosd.h
									
									
									
									
									
								
							| @@ -4,17 +4,12 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: dvbosd.h 1.6 2001/05/01 14:41:42 kls Exp $ | ||||
|  * $Id: dvbosd.h 1.7 2001/07/22 11:49:35 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef __DVBOSD_H | ||||
| #define __DVBOSD_H | ||||
|  | ||||
| // FIXME: these should be defined in ../DVB/driver/dvb.h!!! | ||||
| typedef unsigned int __u32; | ||||
| typedef unsigned short __u16; | ||||
| typedef unsigned char __u8; | ||||
|  | ||||
| #if defined(DEBUG_OSD) || defined(REMOTE_KBD) | ||||
| #include <ncurses.h> | ||||
| #endif | ||||
| @@ -22,57 +17,96 @@ typedef unsigned char __u8; | ||||
| #include <stdio.h> | ||||
| #include "font.h" | ||||
|  | ||||
| #define MAXNUMCOLORS 16 | ||||
|  | ||||
| enum eDvbColor { | ||||
| #ifndef DEBUG_OSD | ||||
|   clrTransparent, | ||||
|   clrTransparent = 0x00000000, | ||||
| #endif | ||||
|   clrBackground, | ||||
|   clrBackground  = 0x7F000000, // 50% gray | ||||
| #ifdef DEBUG_OSD | ||||
|   clrTransparent = clrBackground, | ||||
|   clrBlack = clrBackground, | ||||
| #else | ||||
|   clrBlack, | ||||
|   clrBlack       = 0xFF000000, | ||||
| #endif | ||||
|   clrRed, | ||||
|   clrGreen, | ||||
|   clrYellow, | ||||
|   clrBlue, | ||||
|   clrMagenta, | ||||
|   clrCyan, | ||||
|   clrWhite, | ||||
|   clrRed         = 0xFF1414FC, | ||||
|   clrGreen       = 0xFF24FC24, | ||||
|   clrYellow      = 0xFF24C0FC, | ||||
|   clrMagenta     = 0xFFFC00B0, | ||||
|   clrBlue        = 0xFFFC0000, | ||||
|   clrCyan        = 0xFFFCFC00, | ||||
|   clrWhite       = 0xFFFCFCFC, | ||||
|   }; | ||||
|  | ||||
| class cBitmap { | ||||
| class cPalette { | ||||
| private: | ||||
|   eDvbColor color[MAXNUMCOLORS]; | ||||
|   int maxColors, numColors; | ||||
|   bool used[MAXNUMCOLORS]; | ||||
|   bool fetched[MAXNUMCOLORS]; | ||||
|   bool full; | ||||
| protected: | ||||
|   typedef unsigned char tIndexes[MAXNUMCOLORS]; | ||||
| public: | ||||
|   cPalette(int Bpp); | ||||
|   int Index(eDvbColor Color); | ||||
|   void Reset(void); | ||||
|   const eDvbColor *Colors(int &FirstColor, int &LastColor); | ||||
|   void Take(const cPalette &Palette, tIndexes *Indexes = NULL); | ||||
|   }; | ||||
|  | ||||
| class cBitmap : public cPalette { | ||||
| private: | ||||
|   cFont *font; | ||||
|   eDvbFont fontType; | ||||
|   void SetIndex(int x, int y, char Index); | ||||
|   char *bitmap; | ||||
|   bool clearWithBackground; | ||||
| protected: | ||||
|   int width, height; | ||||
|   char *bitmap; | ||||
|   int dirtyX1, dirtyY1, dirtyX2, dirtyY2; | ||||
|   void Clean(void); | ||||
| public: | ||||
|   cBitmap(int Width, int Height); | ||||
|   cBitmap(int Width, int Height, int Bpp, bool ClearWithBackground = true); | ||||
|   virtual ~cBitmap(); | ||||
|   eDvbFont SetFont(eDvbFont Font); | ||||
|   bool Dirty(void); | ||||
|   bool Dirty(int &x1, int &y1, int &x2, int &y2); | ||||
|   void SetPixel(int x, int y, eDvbColor Color); | ||||
|   void SetBitmap(int x, int y, const cBitmap &Bitmap); | ||||
|   int Width(void) { return width; } | ||||
|   int Width(unsigned char c); | ||||
|   int Width(const char *s); | ||||
|   void Text(int x, int y, const char *s, eDvbColor ColorFg = clrWhite, eDvbColor ColorBg = clrBackground); | ||||
|   void Fill(int x1, int y1, int x2, int y2, eDvbColor Color); | ||||
|   void Clean(void); | ||||
|   void Clear(void); | ||||
|   const char *Data(int x, int y); | ||||
|   }; | ||||
|  | ||||
| class cDvbOsd : public cBitmap { | ||||
| #define MAXNUMWINDOWS 7 // OSD windows are counted 1...7 | ||||
|  | ||||
| class cWindow; | ||||
|  | ||||
| class cDvbOsd { | ||||
| private: | ||||
|   int videoDev; | ||||
|   int numWindows; | ||||
|   int x0, y0; | ||||
|   cWindow *window[MAXNUMWINDOWS]; | ||||
|   void Cmd(OSD_Command cmd, int color = 0, int x0 = 0, int y0 = 0, int x1 = 0, int y1 = 0, const void *data = NULL); | ||||
|   cWindow *GetWindow(int x, int y); | ||||
| public: | ||||
|   cDvbOsd(int VideoDev, int x1, int y1, int x2, int y2, int Bpp); | ||||
|   cDvbOsd(int VideoDev, int x, int y, int w = -1, int h = -1, int Bpp = -1); | ||||
|   ~cDvbOsd(); | ||||
|   bool Create(int x, int y, int w, int h, int Bpp, bool ClearWithBackground = true, eDvbColor Color0 = clrTransparent, eDvbColor Color1 = clrTransparent, eDvbColor Color2 = clrTransparent, eDvbColor Color3 = clrTransparent); | ||||
|   void Flush(void); | ||||
|   void Clear(void); | ||||
|   void Fill(int x1, int y1, int x2, int y2, eDvbColor Color); | ||||
|   void SetBitmap(int x, int y, const cBitmap &Bitmap); | ||||
|   int Width(unsigned char c); | ||||
|   int Width(const char *s); | ||||
|   eDvbFont SetFont(eDvbFont Font); | ||||
|   void Text(int x, int y, const char *s, eDvbColor ColorFg = clrWhite, eDvbColor ColorBg = clrBackground); | ||||
|   }; | ||||
|  | ||||
| #endif //__DVBOSD_H | ||||
|   | ||||
							
								
								
									
										11
									
								
								interface.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								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.36 2001/06/02 09:05:54 kls Exp $ | ||||
|  * $Id: interface.c 1.37 2001/07/22 12:26:28 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "interface.h" | ||||
| @@ -281,14 +281,15 @@ void cInterface::Title(const char *s) | ||||
|  | ||||
| void cInterface::Status(const char *s, eDvbColor FgColor, eDvbColor BgColor) | ||||
| { | ||||
|   ClearEol(0, -2, s ? BgColor : clrBackground); | ||||
|   int Line = (abs(height) == 1) ? 0 : -2; | ||||
|   ClearEol(0, Line, s ? BgColor : clrBackground); | ||||
|   if (s) | ||||
|      Write(0, -2, s, FgColor, BgColor); | ||||
|      Write(0, Line, s, FgColor, BgColor); | ||||
| } | ||||
|  | ||||
| void cInterface::Info(const char *s) | ||||
| { | ||||
|   Open(); | ||||
|   Open(MenuColumns, -1); | ||||
|   isyslog(LOG_INFO, "info: %s", s); | ||||
|   Status(s, clrWhite, clrGreen); | ||||
|   Wait(); | ||||
| @@ -298,7 +299,7 @@ void cInterface::Info(const char *s) | ||||
|  | ||||
| void cInterface::Error(const char *s) | ||||
| { | ||||
|   Open(); | ||||
|   Open(MenuColumns, -1); | ||||
|   esyslog(LOG_ERR, "ERROR: %s", s); | ||||
|   Status(s, clrWhite, clrRed); | ||||
|   Wait(); | ||||
|   | ||||
							
								
								
									
										11
									
								
								menu.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								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.77 2001/07/12 14:56:18 kls Exp $ | ||||
|  * $Id: menu.c 1.78 2001/07/22 12:27:51 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "menu.h" | ||||
| @@ -585,7 +585,7 @@ cMenuChannelItem::cMenuChannelItem(int Index, cChannel *Channel) | ||||
|   index = Index; | ||||
|   channel = Channel; | ||||
|   if (channel->groupSep) | ||||
|      SetColor(clrWhite, clrBlue); | ||||
|      SetColor(clrWhite, clrCyan); | ||||
|   Set(); | ||||
| } | ||||
|  | ||||
| @@ -1802,7 +1802,7 @@ cDisplayChannel::cDisplayChannel(int Number, bool Switched, bool Group) | ||||
|   lines = 0; | ||||
|   oldNumber = number = 0; | ||||
|   cChannel *channel = Group ? Channels.Get(Number) : Channels.GetByNumber(Number); | ||||
|   Interface->Open(MenuColumns, 5); | ||||
|   Interface->Open(MenuColumns, -5); | ||||
|   if (channel) { | ||||
|      DisplayChannel(channel); | ||||
|      DisplayInfo(); | ||||
| @@ -1816,7 +1816,7 @@ cDisplayChannel::cDisplayChannel(eKeys FirstKey) | ||||
|   oldNumber = cDvbApi::CurrentChannel(); | ||||
|   number = 0; | ||||
|   lastTime = time_ms(); | ||||
|   Interface->Open(MenuColumns, 5); | ||||
|   Interface->Open(MenuColumns, -5); | ||||
|   ProcessKey(FirstKey); | ||||
| } | ||||
|  | ||||
| @@ -1843,7 +1843,6 @@ void cDisplayChannel::DisplayChannel(const cChannel *Channel) | ||||
|   struct tm *now = localtime(&t); | ||||
|   snprintf(buffer, BufSize, "%02d:%02d", now->tm_hour, now->tm_min); | ||||
|   Interface->Write(-5, 0, buffer); | ||||
|   Interface->Flush(); | ||||
| } | ||||
|  | ||||
| void cDisplayChannel::DisplayInfo(void) | ||||
| @@ -2100,7 +2099,7 @@ public: | ||||
|   }; | ||||
|  | ||||
| cProgressBar::cProgressBar(int Width, int Height, int Current, int Total, const cMarks &Marks) | ||||
| :cBitmap(Width, Height) | ||||
| :cBitmap(Width, Height, 2) | ||||
| { | ||||
|   total = Total; | ||||
|   if (total > 0) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user