vdr  2.7.6
PLUGINS/src/pictures/player.c
Go to the documentation of this file.
1 /*
2  * player.c: A player for still pictures
3  *
4  * See the README file for copyright information and how to reach the author.
5  *
6  * $Id: player.c 5.2 2025/03/02 11:03:35 kls Exp $
7  */
8 
9 #include "player.h"
10 #include <vdr/remote.h>
11 #include <vdr/tools.h>
12 
13 int SlideShowDelay = 3; // seconds
14 
15 cString HandleUnderscores(const char *s)
16 {
17  // Skip anything before and including the first '_' and replace
18  // any remaining '_' with blanks:
19  const char *p = strchr(s, '_');
20  if (p) {
21  p++;
22  char buf[strlen(p) + 1];
23  strcpy(buf, p);
24  return strreplace(buf, '_', ' ');
25  }
26  return s;
27 }
28 
29 // --- cPicturePlayer --------------------------------------------------------
30 
31 class cPicturePlayer : public cPlayer {
32 private:
33  int size;
34  int length;
36  virtual void Activate(bool On) override;
37 public:
38  cPicturePlayer(void);
40  void SetPicture(const char *FileName);
41  };
42 
44 {
45  size = KILOBYTE(100); // will be adjusted automatically if files are larger
46  length = 0;
47  buffer = MALLOC(uchar, size);
48 }
49 
51 {
52  free(buffer);
53 }
54 
56 {
57  if (length > 0)
59 }
60 
61 void cPicturePlayer::SetPicture(const char *FileName)
62 {
63  int f = open(FileName, O_RDONLY);
64  if (f >= 0) {
65  for (;;) {
66  length = read(f, buffer, size);
67  if (length > 0) {
68  if (length >= size) {
69  int NewSize = size * 3 / 2;
70  if (uchar *NewBuffer = (uchar *)realloc(buffer, NewSize)) {
71  buffer = NewBuffer;
72  size = NewSize;
73  }
74  else {
75  LOG_ERROR_STR("out of memory");
76  break;
77  }
78  lseek(f, 0, SEEK_SET);
79  continue;
80  }
82  }
83  else
84  LOG_ERROR_STR(FileName);
85  break;
86  }
87  close(f);
88  }
89  else
90  LOG_ERROR_STR(FileName);
91 }
92 
93 // --- cPictureControl -------------------------------------------------------
94 
97 
98 cPictureControl::cPictureControl(cPictureEntry *Pictures, const cPictureEntry *PictureEntry, bool SlideShow)
99 :cControl(NULL)
100 {
101  player = new cPicturePlayer;
102  SetPlayer(player);
103  pictures = Pictures;
104  pictureEntry = PictureEntry;
105  osd = NULL;
106  lastPath = "/";
108  slideShow = SlideShow;
109  alwaysDisplayCaption = false;
111  active++;
112 }
113 
115 {
116  active--;
117  delete osd;
118  delete player;
119  delete pictures;
120 }
121 
122 void cPictureControl::NextPicture(int Direction)
123 {
124  if (Direction) {
125  const cPictureEntry *pe = Direction > 0 ? pictureEntry->NextPicture() : pictureEntry->PrevPicture();
126  if (pe)
127  pictureEntry = pe;
128  }
129  if (pictureEntry) {
131  DisplayCaption();
132  }
133 }
134 
136 {
137  // This only works reliable if a directory contains only subdirectories or pictures, not both!
138  if (Direction) {
139  const cPictureEntry *pe = Direction > 0 ? pictureEntry->Parent()->Entries()->Last()->NextPicture() : pictureEntry->Parent()->Entries()->First()->PrevPicture();
140  if (pe && Direction < 0)
141  pe = pe->Parent()->Entries()->First();
142  if (pe && pe != pictureEntry) {
143  pictureEntry = pe;
145  DisplayCaption();
146  }
147  }
148 }
149 
150 static void DrawTextOutlined(cOsd *Osd, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font)
151 {
152  for (int dx = -1; dx <= 1; dx++) {
153  for (int dy = -1; dy <= 1; dy++) {
154  if (dx || dy)
155  Osd->DrawText(x + dx, y + dy, s, ColorBg, clrTransparent, Font);
156  }
157  }
158  Osd->DrawText(x, y, s, ColorFg, clrTransparent, Font);
159 }
160 
162 {
163  bool Force = false;
164  cString Path = pictureEntry->Path();
165  lastDisplayed = Path + strlen(pictures->Name()) + 1;
166  const char *p = strrchr(Path, '/');
167  const char *q = strrchr(lastPath, '/');
168  if (p && q) {
169  int lp = p - Path;
170  int lq = q - lastPath;
171  if (lp != lq || strncmp(lastPath, Path, lp)) {
172  lastPath = Path;
173  Force = true;
174  }
175  }
176  if (!alwaysDisplayCaption && !Force) {
177  DELETENULL(osd);
178  return;
179  }
180  const cFont *Font = cFont::GetFont(fontOsd);
181  int w = cOsd::OsdWidth();
182  int h = 2 * Font->Height();
183  if (!osd) {
185  tArea Areas[] = { { 0, 0, w - 1, h - 1, 8 } };
186  if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
187  osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
188  else {
189  tArea Areas[] = { { 0, 0, w - 1, h - 1, 4 } };
190  osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
191  }
192  }
193  const char *Year = pictureEntry->Parent()->Parent() ? pictureEntry->Parent()->Parent()->Name() : "";
194  cString Description = HandleUnderscores(pictureEntry->Parent()->Name());
195  osd->DrawRectangle(0, 0, w - 1, h - 1, clrTransparent);
196  DrawTextOutlined(osd, 0, 0, Description, clrWhite, clrBlack, Font);
197  DrawTextOutlined(osd, 0, h / 2, Year, clrWhite, clrBlack, Font);
198  struct stat sb;
199  if (stat(Path, &sb) == 0) {
200  cString Time = DayDateTime(sb.st_mtime);
201  DrawTextOutlined(osd, w - Font->Width(Time), h / 2, Time, clrWhite, clrBlack, Font);
202  }
203  p++;
204  Path.Truncate(-4); // don't display the ".mpg" extension
205  DrawTextOutlined(osd, w - Font->Width(p), 0, p, clrWhite, clrBlack, Font);
206  osd->Flush();
207 }
208 
210 {
211  return tr("Pictures");
212 }
213 
215 {
216  switch (int(Key)) {
217  case kUp:
218  case kPlay: slideShowDelay.Set();
219  slideShow = true;
220  break;
221  case kDown:
222  case kPause: slideShow = false;
223  break;
224  case kLeft|k_Repeat:
225  case kLeft: NextPicture(-1);
226  slideShow = false;
227  break;
228  case kRight|k_Repeat:
229  case kRight: NextPicture(+1);
230  slideShow = false;
231  break;
232  case kOk: if (osd && !alwaysDisplayCaption)
233  DELETENULL(osd);
234  else {
236  DisplayCaption();
237  }
238  break;
239  case kGreen:
240  case kPrev: NextDirectory(-1);
241  slideShow = false;
242  break;
243  case kYellow:
244  case kNext: NextDirectory(+1);
245  slideShow = false;
246  break;
247  case kBlue:
248  case kStop: return osEnd;
249  case kBack: slideShow = false;
250  cRemote::CallPlugin(PLUGIN_NAME_I18N);
251  break;
252  default: break;
253  }
254  if (slideShow && slideShowDelay.TimedOut()) {
255  NextPicture(+1);
257  }
258  return osContinue;
259 }
260 
262 {
263  return lastDisplayed;
264 }
static void DrawTextOutlined(cOsd *Osd, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font)
cString HandleUnderscores(const char *s)
void SetPlayer(cPlayer *Player)
Definition: player.h:113
virtual int Width(void) const override
Returns the original character width as requested when the font was created, or 0 if the default widt...
Definition: skincurses.c:23
virtual int Height(void) const override
Returns the height of this font in pixel (all characters have the same height).
Definition: skincurses.c:26
Definition: font.h:37
static const cFont * GetFont(eDvbFont Font)
Gets the given Font, which was previously set by a call to SetFont().
Definition: font.c:412
const T * Last(void) const
Returns the last element in this list, or NULL if the list is empty.
Definition: tools.h:645
const T * First(void) const
Returns the first element in this list, or NULL if the list is empty.
Definition: tools.h:643
static cOsd * NewOsd(int Left, int Top, uint Level=OSD_LEVEL_DEFAULT)
Returns a pointer to a newly created cOsd object, which will be located at the given coordinates.
Definition: osd.c:2290
The cOsd class is the interface to the "On Screen Display".
Definition: osd.h:753
static int OsdHeight(void)
Definition: osd.h:831
virtual eOsdError SetAreas(const tArea *Areas, int NumAreas)
Sets the sub-areas to the given areas.
Definition: osd.c:2092
virtual eOsdError CanHandleAreas(const tArea *Areas, int NumAreas)
Checks whether the OSD can display the given set of sub-areas.
Definition: osd.c:2070
static int OsdTop(void)
Definition: osd.h:829
virtual void Flush(void)
Actually commits all data to the OSD hardware.
Definition: osd.c:2266
virtual void DrawRectangle(int x1, int y1, int x2, int y2, tColor Color)
Draws a filled rectangle defined by the upper left (x1, y1) and lower right (x2, y2) corners with the...
Definition: osd.c:2236
static int OsdLeft(void)
Definition: osd.h:828
static int OsdWidth(void)
Definition: osd.h:830
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)
Draws the given string at coordinates (x, y) with the given foreground and background color and font.
Definition: osd.c:2226
virtual cString GetHeader(void) override
This can be used by players that don't play a cRecording, but rather do something completely differen...
static const char * LastDisplayed(void)
virtual eOSState ProcessKey(eKeys Key) override
void NextDirectory(int Direction)
virtual ~cPictureControl() override
cPictureControl(cPictureEntry *Pictures, const cPictureEntry *PictureEntry, bool SlideShow=false)
void NextPicture(int Direction)
const cPictureEntry * pictureEntry
const char * Name(void) const
Definition: entry.h:25
const cPictureEntry * PrevPicture(const cPictureEntry *This=NULL) const
Definition: entry.c:106
const cPictureEntry * Parent(void) const
Definition: entry.h:26
const cPictureEntry * NextPicture(const cPictureEntry *This=NULL) const
Definition: entry.c:125
bool IsDirectory(void) const
Definition: entry.h:27
const cList< cPictureEntry > * Entries(void) const
Definition: entry.c:66
cString Path(void) const
Definition: entry.c:38
virtual void Activate(bool On) override
void SetPicture(const char *FileName)
Definition: player.h:16
void DeviceStillPicture(const uchar *Data, int Length)
Definition: player.h:36
static bool CallPlugin(const char *Plugin)
Initiates calling the given plugin's main menu function.
Definition: remote.c:151
int AntiAlias
Definition: config.h:344
Definition: tools.h:178
cString & Truncate(int Index)
Truncate the string at the given Index (if Index is < 0 it is counted from the end of the string).
Definition: tools.c:1179
void Set(int Ms=0)
Sets the timer.
Definition: tools.c:808
bool TimedOut(void) const
Definition: tools.c:813
cSetup Setup
Definition: config.c:372
@ fontOsd
Definition: font.h:22
uint32_t tColor
Definition: font.h:29
#define tr(s)
Definition: i18n.h:85
eKeys
Definition: keys.h:16
@ kRight
Definition: keys.h:23
@ kPause
Definition: keys.h:32
@ kUp
Definition: keys.h:17
@ kPlay
Definition: keys.h:31
@ kDown
Definition: keys.h:18
@ kGreen
Definition: keys.h:25
@ kStop
Definition: keys.h:33
@ kLeft
Definition: keys.h:22
@ kBlue
Definition: keys.h:27
@ kPrev
Definition: keys.h:38
@ kYellow
Definition: keys.h:26
@ kBack
Definition: keys.h:21
@ k_Repeat
Definition: keys.h:61
@ kNext
Definition: keys.h:37
@ kOk
Definition: keys.h:20
#define OSD_LEVEL_SUBTITLES
Definition: osd.h:22
@ oeOk
Definition: osd.h:44
@ clrWhite
Definition: osd.h:41
@ clrBlack
Definition: osd.h:34
@ clrTransparent
Definition: osd.h:32
eOSState
Definition: osdbase.h:18
@ osEnd
Definition: osdbase.h:34
@ osContinue
Definition: osdbase.h:19
static const cCursesFont Font
Definition: skincurses.c:31
Definition: osd.h:298
char * strreplace(char *s, char c1, char c2)
Definition: tools.c:142
cString DayDateTime(time_t t)
Converts the given time to a string of the form "www dd.mm. hh:mm".
Definition: tools.c:1260
#define LOG_ERROR_STR(s)
Definition: tools.h:40
unsigned char uchar
Definition: tools.h:31
#define MALLOC(type, size)
Definition: tools.h:47
void DELETENULL(T *&p)
Definition: tools.h:49
#define KILOBYTE(n)
Definition: tools.h:44