mirror of
https://github.com/vdr-projects/vdr.git
synced 2025-03-01 10:50:46 +00:00
Compare commits
49 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
dd71a004e2 | ||
|
45091fbd72 | ||
|
988d5aebfa | ||
|
8c3671fae6 | ||
|
2a12af481a | ||
|
7817e64695 | ||
|
ebbaa39098 | ||
|
d3dcbbd4f2 | ||
|
3045995bbc | ||
|
1b4233d6ad | ||
|
34aa8fe8b4 | ||
|
baa97e9ff1 | ||
|
03afc4a353 | ||
|
ef4ebeb7ee | ||
|
80d8851e62 | ||
|
ead135f716 | ||
|
49dc61a92c | ||
|
af0309cc40 | ||
|
4ed7421b1c | ||
|
3058354dba | ||
|
20a8c5d240 | ||
|
0749a34342 | ||
|
e595eed57d | ||
|
a7576f0b6c | ||
|
657e5dda5d | ||
|
8fb6a2b24b | ||
|
53cac302d8 | ||
|
2c6c014dd8 | ||
|
a7071f580e | ||
|
de5327a048 | ||
|
7ab94c7bcb | ||
|
0f80fc5e86 | ||
|
d169f30e5c | ||
|
7a1842cba6 | ||
|
e4e9d7a55f | ||
|
ccbef6ce6c | ||
|
7461a1ba3a | ||
|
bb55e3036e | ||
|
bbf2cca198 | ||
|
8ce034d124 | ||
|
4030698007 | ||
|
66fea5c9f1 | ||
|
285574eeaa | ||
|
55cfb057e0 | ||
|
b4c538cff7 | ||
|
5a626fef9f | ||
|
2bcd8ba8f3 | ||
|
2dacc776bd | ||
|
a91d687a1a |
26
CONTRIBUTORS
26
CONTRIBUTORS
@ -2585,6 +2585,17 @@ Markus Ehrnsperger <markus.ehrnsperger@googlemail.com>
|
||||
was no event with RunningStatus() >= SI::RunningStatusPausing
|
||||
for reporting problem with duplicate events if they are moved to a lower table ID and
|
||||
at the same time get a new event ID
|
||||
for reporting a bug in handling negative values in cSource::Position() on
|
||||
systems where 'int' is 64 bit
|
||||
for suggesting a fix for expiring of one-time VPS timers in case there is more than
|
||||
one event with the same VPS time
|
||||
for fixing handling margins for timers that are not VPS controlled and not spawned
|
||||
for implementing cStatus::OsdItem2() with the information whether the item is selectable
|
||||
for reporting an improper call of cStatus::OsdCurrentItem() before cStatus::OsdItem2()
|
||||
for fixing unnecessary calls to DisplayCurrent() for editable menu items
|
||||
for implementing cStatus::OsdCurrentItem2() with the index of the current item
|
||||
for adding missing calls to cStatus::MsgOsdStatusMessage() and implementing
|
||||
cStatus::OsdStatusMessage2() with the type of the message
|
||||
|
||||
Werner Färber <w.faerber@gmx.de>
|
||||
for reporting a bug in handling the cPluginManager::Active() result when pressing
|
||||
@ -2845,6 +2856,10 @@ Winfried K
|
||||
for adding a missing initialization of cChannel::nameSourceMode
|
||||
for suggesting to make APIVERSION a simple number, independent from VDRVERSION
|
||||
for reporting a compiler warning with gcc 14.1.0
|
||||
for suggesting to remove defining DEPRECATED_* macros with value 0, because this
|
||||
is the preprocessor's default
|
||||
for suggesting a fix for handling negative values in cSource::Position() on
|
||||
systems where 'int' is 64 bit
|
||||
|
||||
Hans-Werner Hilse <hilse@web.de>
|
||||
for adding the command line option --userdump to enable core dumps in case VDR
|
||||
@ -3360,6 +3375,15 @@ Stefan Hofmann <stefan.hofmann@t-online.de>
|
||||
for suggesting to implement support for remote controls that only have a combined
|
||||
"Play/Pause" key instead of separate keys for "Play" and "Pause"
|
||||
for a fix for compilers that don't like non-constant format strings
|
||||
for suggesting to implement jumping between errors while replaying a recording
|
||||
for adding vdrrootdir and incdir to vdr.pc
|
||||
for fixing some typos in the translation files
|
||||
for adding 1 to Utf8BufSize() for worst case
|
||||
for adding a header to the backtrace
|
||||
for adding parameter checks to strn0cpy()
|
||||
for making the info files of recordings only be re-read if they have been modified
|
||||
for reporting missing setting the file name of the info file after renaming a recording
|
||||
for adding '~' to the list of delimiters in cTextWrapper
|
||||
|
||||
Stefan Blochberger <Stefan.Blochberger@gmx.de>
|
||||
for suggesting to automatically display the progress display whenever replay of a
|
||||
@ -3792,3 +3816,5 @@ Jose Angel <joseangelpp@gmail.com>
|
||||
|
||||
Andreas Baierl <post@andreasbaierl.de>
|
||||
for implementing scaling images
|
||||
for reporting a problem in the progress display when switching from "pause" to
|
||||
"slow back"
|
||||
|
69
HISTORY
69
HISTORY
@ -10020,3 +10020,72 @@ Video Disk Recorder Revision History
|
||||
- Increased the bpp of cProgressBar to 4 to handle all different colors.
|
||||
- Fixed a problem with duplicate events if they are moved to a lower table ID and at the
|
||||
same time get a new event ID (reported by Markus Ehrnsperger).
|
||||
|
||||
2024-10-12: Version 2.7.3
|
||||
|
||||
- Removed defining DEPRECATED_* macros with value 0, because this is the preprocessor's
|
||||
default (suggested by Winfried Köhler).
|
||||
- Fixed error checking in case of large PTS discontinuities.
|
||||
- Fixed handling negative values in cSource::Position() on systems where 'int' is 64 bit
|
||||
(reported by Markus Ehrnsperger, fix suggested by Winfried Köhler).
|
||||
- Fixed expiring of one-time VPS timers in case there is more than one event with the
|
||||
same VPS time (suggested by Markus Ehrnsperger).
|
||||
- The Channel+/- keys can now be used to jump between errors while replaying a recording
|
||||
(suggested by Stefan Hofmann).
|
||||
- Added vdrrootdir and incdir to vdr.pc (thanks to Stefan Hofmann).
|
||||
|
||||
2025-02-26: Version 2.7.4
|
||||
|
||||
- Removed all DEPRECATED_* code.
|
||||
- Fixed error checking in case the fps value can't be determined by the frame parser.
|
||||
- Updated the Italian OSD texts (thanks to Diego Pierotto).
|
||||
- The VDR homepage is now accessible via HTTPS.
|
||||
- Updated the Finnish OSD texts (thanks to Rolf Ahrenberg).
|
||||
- Fixed some typos in the translation files (thanks to Stefan Hofmann).
|
||||
- Added some missing locking.
|
||||
- TS packets with errors are now skipped when parsing for frames.
|
||||
- Fixed handling the fps value if it can't be determined from the video data.
|
||||
- Fixed accessing a timer's event schedule in case the event has been removed from the
|
||||
schedule.
|
||||
- Fixed a possible deadlock when canceling an editing process.
|
||||
- Checking for VPS control is now limited to local timers.
|
||||
- Added 1 to Utf8BufSize() for worst case (thanks to Stefan Hofmann).
|
||||
- Fixed handling margins for timers that are not VPS controlled and not spawned (thanks
|
||||
to Markus Ehrnsperger).
|
||||
- Added a header to the backtrace (thanks to Stefan Hofmann).
|
||||
- Added parameter checks to strn0cpy() (thanks to Stefan Hofmann). Same for Utf8Strn0Cpy().
|
||||
- The info files of recordings are now only re-read if they have been modified (thanks
|
||||
to Stefan Hofmann).
|
||||
- The new virtual function cStatus::OsdItem2() can be used to get the information whether
|
||||
a menu item is selectable (thanks to Markus Ehrnsperger). Plugins that implemented
|
||||
cStatus::OsdItem() will still work as before, because the default implementation of
|
||||
cStatus::OsdItem2() calls cStatus::OsdItem().
|
||||
APIVERSNUM is now 30006.
|
||||
- Fixed setting the file name of the info file after renaming a recording (reported by
|
||||
Stefan Hofmann).
|
||||
- Fixed an improper call of cStatus::OsdCurrentItem() before cStatus::OsdItem2() (reported
|
||||
by Markus Ehrnsperger).
|
||||
- Fixed an unnecessary redisplay of the menu when pressing a hotkey.
|
||||
- Fixed unnecessary calls to DisplayCurrent() for editable menu items (thanks to Markus
|
||||
Ehrnsperger).
|
||||
- The new virtual function cStatus::OsdCurrentItem2() can be used to get the index of the
|
||||
current menu item (thanks to Markus Ehrnsperger). Plugins that implemented
|
||||
cStatus::OsdCurrentItem() will still work as before, because the default implementation
|
||||
of cStatus::OsdCurrentItem2() calls cStatus::OsdCurrentItem().
|
||||
- Fixed unnecessary calls to cStatus::OsdCurrentItem2() when scrolling.
|
||||
- Added missing calls to cStatus::MsgOsdStatusMessage() and added the new virtual function
|
||||
cStatus::OsdStatusMessage2(), which can be used to get the type of the message (thanks
|
||||
to Markus Ehrnsperger). Plugins that implemented cStatus::OsdStatusMessage() will still
|
||||
work as before, because the default implementation of cStatus::OsdStatusMessage2() calls
|
||||
cStatus::OsdStatusMessage().
|
||||
- Adjusted PLUGINS.html to the new API version numbering introduced in version 2.7.2.
|
||||
- The function cPlugin::MainThreadHook() has been deprecated and may be removed in future
|
||||
versions. Use proper locking instead.
|
||||
- Fixed unnecessary redisplays of menus.
|
||||
- Added '~' to the list of delimiters in cTextWrapper (thanks to Stefan Hofmann).
|
||||
- Fixed progress display when switching from "pause" to "slow back" (reported by Andreas
|
||||
Baierl).
|
||||
- Fixed spurious fast frames when switching from "slow back" to "slow forward".
|
||||
- Fixed cPtsIndex::FindFrameNumber() to handle the case where Pts points to an I-frame.
|
||||
- Added missing locks to SetMenuItem() functions.
|
||||
- Revised locking in cMenuSchedule and cMenuWhatsOn.
|
||||
|
4
MANUAL
4
MANUAL
@ -50,8 +50,8 @@ Version 2.7
|
||||
Next Next/previous channel group (in live tv mode)
|
||||
Prev or next/previous editing mark (in replay mode)
|
||||
|
||||
Channel+ channel up
|
||||
Channel- channel down
|
||||
Channel+ channel up (live view), next error (replay)
|
||||
Channel- channel down (live view), previous error (replay)
|
||||
PrevChannel previous channel
|
||||
|
||||
Power shutdown
|
||||
|
@ -6,7 +6,7 @@
|
||||
# See the main source file 'vdr.c' for copyright information and
|
||||
# how to reach the author.
|
||||
#
|
||||
# $Id: Make.config.template 5.1 2022/11/26 13:37:06 kls Exp $
|
||||
# $Id: Make.config.template 5.2 2024/10/11 14:21:04 kls Exp $
|
||||
|
||||
### The C compiler and options:
|
||||
|
||||
@ -33,14 +33,15 @@ endif
|
||||
# Default directories (adjust as necessary or desired):
|
||||
|
||||
#PREFIX = /usr/local
|
||||
#BINDIR = $(PREFIX)/bin
|
||||
#INCDIR = $(PREFIX)/include
|
||||
#LIBDIR = $(PREFIX)/lib/vdr
|
||||
#LOCDIR = $(PREFIX)/share/locale
|
||||
#MANDIR = $(PREFIX)/share/man
|
||||
#PCDIR = $(PREFIX)/lib/pkgconfig
|
||||
#RESDIR = $(PREFIX)/share/vdr
|
||||
#DVBDIR = /usr/src/v4l-dvb/linux/include/uapi
|
||||
#VDRROOT = $(PREFIX)
|
||||
#BINDIR = $(VDRROOT)/bin
|
||||
#INCDIR = $(VDRROOT)/include
|
||||
#LIBDIR = $(VDRROOT)/lib
|
||||
#LOCDIR = $(VDRROOT)/locale
|
||||
#MANDIR = $(VDRROOT)/man
|
||||
#PCDIR = $(VDRROOT)/pkgconfig
|
||||
#RESDIR = $(VDRROOT)/share
|
||||
#DVBDIR = /usr/include
|
||||
|
||||
#VIDEODIR = /srv/vdr/video
|
||||
#CONFDIR = /var/lib/vdr
|
||||
|
26
Makefile
26
Makefile
@ -4,7 +4,7 @@
|
||||
# See the main source file 'vdr.c' for copyright information and
|
||||
# how to reach the author.
|
||||
#
|
||||
# $Id: Makefile 5.2 2024/01/05 14:16:16 kls Exp $
|
||||
# $Id: Makefile 5.4 2024/10/21 19:01:16 kls Exp $
|
||||
|
||||
.DELETE_ON_ERROR:
|
||||
|
||||
@ -46,13 +46,14 @@ ARGSDIR ?= /etc/vdr/conf.d
|
||||
CACHEDIR ?= /var/cache/vdr
|
||||
|
||||
PREFIX ?= /usr/local
|
||||
BINDIR ?= $(PREFIX)/bin
|
||||
INCDIR ?= $(PREFIX)/include
|
||||
LIBDIR ?= $(PREFIX)/lib/vdr
|
||||
LOCDIR ?= $(PREFIX)/share/locale
|
||||
MANDIR ?= $(PREFIX)/share/man
|
||||
PCDIR ?= $(PREFIX)/lib/pkgconfig
|
||||
RESDIR ?= $(PREFIX)/share/vdr
|
||||
VDRROOT ?= $(PREFIX)
|
||||
BINDIR ?= $(VDRROOT)/bin
|
||||
INCDIR ?= $(VDRROOT)/include
|
||||
LIBDIR ?= $(VDRROOT)/lib/vdr
|
||||
LOCDIR ?= $(VDRROOT)/share/locale
|
||||
MANDIR ?= $(VDRROOT)/share/man
|
||||
PCDIR ?= $(VDRROOT)/lib/pkgconfig
|
||||
RESDIR ?= $(VDRROOT)/share/vdr
|
||||
|
||||
# Source documentation
|
||||
|
||||
@ -169,7 +170,9 @@ make-libsi: # empty rule makes sure the sub-make for libsi is always called
|
||||
|
||||
.PHONY: vdr.pc
|
||||
vdr.pc:
|
||||
@echo "bindir=$(BINDIR)" > $@
|
||||
@echo "vdrrootdir=$(VDRROOT)" > $@
|
||||
@echo "bindir=$(BINDIR)" >> $@
|
||||
@echo "incdir=$(INCDIR)" >> $@
|
||||
@echo "mandir=$(MANDIR)" >> $@
|
||||
@echo "videodir=$(VIDEODIR)" >> $@
|
||||
@echo "configdir=$(CONFDIR)" >> $@
|
||||
@ -185,7 +188,7 @@ vdr.pc:
|
||||
@echo "" >> $@
|
||||
@echo "Name: VDR" >> $@
|
||||
@echo "Description: Video Disk Recorder" >> $@
|
||||
@echo "URL: http://www.tvdr.de/" >> $@
|
||||
@echo "URL: https://www.tvdr.de/" >> $@
|
||||
@echo "Version: $(VDRVERSION)" >> $@
|
||||
@echo "Cflags: \$${cflags}" >> $@
|
||||
|
||||
@ -320,6 +323,7 @@ install-doc:
|
||||
|
||||
install-plugins: plugins
|
||||
@-for i in `ls $(PLUGINDIR)/src | grep -v '[^a-z0-9]'`; do\
|
||||
echo; echo "*** Plugin $$i:";\
|
||||
$(MAKE) --no-print-directory -C "$(PLUGINDIR)/src/$$i" VDRDIR=$(CWD) DESTDIR=$(DESTDIR) install;\
|
||||
done
|
||||
@if [ -d $(PLUGINDIR)/lib ] ; then\
|
||||
@ -356,7 +360,7 @@ srcdoc:
|
||||
clean:
|
||||
@$(MAKE) --no-print-directory -C $(LSIDIR) clean
|
||||
@-rm -f $(OBJS) $(DEPFILE) vdr vdr.pc core* *~
|
||||
@-rm -rf $(LOCALEDIR) $(PODIR)/*.mo $(PODIR)/*.pot
|
||||
@-rm -rf $(LOCALEDIR) $(PODIR)/*~ $(PODIR)/*.mo $(PODIR)/*.pot
|
||||
@-rm -rf include
|
||||
@-rm -rf srcdoc
|
||||
CLEAN: clean
|
||||
|
41
PLUGINS.html
41
PLUGINS.html
@ -35,7 +35,7 @@ modified {
|
||||
<p>
|
||||
Copyright © 2021 Klaus Schmidinger<br>
|
||||
<a href="mailto:vdr@tvdr.de">vdr@tvdr.de</a><br>
|
||||
<a href="http://www.tvdr.de">www.tvdr.de</a>
|
||||
<a href="https://www.tvdr.de">www.tvdr.de</a>
|
||||
</div>
|
||||
<p>
|
||||
VDR provides an easy to use plugin interface that allows additional functionality
|
||||
@ -74,7 +74,6 @@ structures and allows it to hook itself into specific areas to perform special a
|
||||
<li><a href="#Main menu entry">Main menu entry</a>
|
||||
<li><a href="#User interaction">User interaction</a>
|
||||
<li><a href="#Housekeeping">Housekeeping</a>
|
||||
<li><a href="#Main thread hook">Main thread hook</a>
|
||||
<li><a href="#Activity">Activity</a>
|
||||
<li><a href="#Wakeup">Wakeup</a>
|
||||
<li><a href="#Setup parameters">Setup parameters</a>
|
||||
@ -166,7 +165,7 @@ is used:
|
||||
VDR/PLUGINS/src
|
||||
VDR/PLUGINS/src/hello
|
||||
VDR/PLUGINS/lib
|
||||
VDR/PLUGINS/lib/libvdr-hello.so.1.1.0
|
||||
VDR/PLUGINS/lib/libvdr-hello.so.1
|
||||
</pre></td></tr></table><p>
|
||||
|
||||
The <tt>src</tt> directory contains one subdirectory for each plugin, which carries
|
||||
@ -185,7 +184,7 @@ The <tt>lib</tt> directory contains the dynamically loadable libraries of all
|
||||
available plugins. Note that the names of these files are created by concatenating
|
||||
<p>
|
||||
<table border=2>
|
||||
<tr><td align=center><b><tt>libvdr-</tt></b></td><td align=center><b><tt>hello</tt></b></td><td align=center><b><tt>.so.</tt></b></td><td align=center><b><tt>1.1.0</tt></b></td></tr>
|
||||
<tr><td align=center><b><tt>libvdr-</tt></b></td><td align=center><b><tt>hello</tt></b></td><td align=center><b><tt>.so.</tt></b></td><td align=center><b><tt>1</tt></b></td></tr>
|
||||
<tr><td align=center><small>VDR plugin<br>library prefix</small></td><td align=center><small>name of<br>the plugin</small></td><td align=center><small>shared object<br>indicator</small></td><td align=center><small>API version number<br>this plugin was<br>compiled for</small></td></tr>
|
||||
</table>
|
||||
<p>
|
||||
@ -196,6 +195,11 @@ the current VDR version. That way minor fixes to VDR, that don't require changes
|
||||
to the VDR header files, can be made without requiring all plugins to be
|
||||
recompiled.
|
||||
<p>
|
||||
While in earlier versions of VDR the API version number was closely related to the
|
||||
VDR version number, starting with VDR version 2.7.2 the API version number was changed
|
||||
from a dot separated, three part number to a single integer, completely unrelated to
|
||||
the VDR version. This was done to avoid confusion.
|
||||
<p>
|
||||
The plugin library files can be stored in any directory. If the default organization
|
||||
is not used, the path to the plugin directory has be be given to VDR through the
|
||||
<b><tt>-L</tt></b> option.
|
||||
@ -391,13 +395,7 @@ just like shown in the above example. This is a convention that allows the <tt>M
|
||||
to extract the version number when generating the file name for the distribution archive.
|
||||
<p>
|
||||
A new plugin project should start with version number <tt>0.0.1</tt> and should reach
|
||||
version <tt>1.0.0</tt> once it is completely operative and well tested. Following the
|
||||
Linux kernel version numbering scheme, versions with <i>even</i> release numbers
|
||||
(like <tt>1.0.x</tt>, <tt>1.2.x</tt>, <tt>1.4.x</tt>...) should be stable releases,
|
||||
while those with <i>odd</i> release numbers (like <tt>1.1.x</tt>, <tt>1.3.x</tt>,
|
||||
<tt>1.5.x</tt>...) are usually considered "under development". The three parts of
|
||||
a version number are not limited to single digits, so a version number of <tt>1.2.15</tt>
|
||||
would be acceptable.
|
||||
version <tt>1.0.0</tt> once it is completely operative and well tested.
|
||||
|
||||
<hr><h2><a name="Description">Description</a></h2>
|
||||
|
||||
@ -693,27 +691,6 @@ interaction is possible. If a specific action takes longer than a few seconds,
|
||||
the plugin should launch a separate thread to do this.
|
||||
</b>
|
||||
|
||||
<hr><h2><a name="Main thread hook">Main thread hook</a></h2>
|
||||
|
||||
<div class="blurb">Pushing in...</div><p>
|
||||
|
||||
Normally a plugin only reacts on user input if directly called through its
|
||||
<a href="#Main menu entry">main menu entry</a>, or performs some background
|
||||
activity in a separate thread. However, sometimes a plugin may need to do
|
||||
something in the context of the main program thread, without being explicitly
|
||||
called up by the user. In such a case it can implement the function
|
||||
|
||||
<p><table><tr><td class="code"><pre>
|
||||
virtual void MainThreadHook(void);
|
||||
</pre></td></tr></table><p>
|
||||
|
||||
in which it can do this. This function is called for every plugin once during
|
||||
every cycle of VDR's main program loop, which typically happens once every
|
||||
second.
|
||||
<b>Be very careful when using this function, and make sure you return from it
|
||||
as soon as possible! If you spend too much time in this function, the user
|
||||
interface performance will become sluggish!</b>
|
||||
|
||||
<hr><h2><a name="Activity">Activity</a></h2>
|
||||
|
||||
<div class="blurb">Now is not a good time!</div><p>
|
||||
|
@ -2,9 +2,9 @@ This is a "plugin" for the Video Disk Recorder (VDR).
|
||||
|
||||
Written by: Klaus Schmidinger <vdr@tvdr.de>
|
||||
|
||||
Project's homepage: http://www.tvdr.de
|
||||
Project's homepage: https://www.tvdr.de
|
||||
|
||||
Latest version available at: http://www.tvdr.de
|
||||
Latest version available at: https://www.tvdr.de
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -2,9 +2,9 @@ This is a "plugin" for the Video Disk Recorder (VDR).
|
||||
|
||||
Written by: Klaus Schmidinger <vdr@tvdr.de>
|
||||
|
||||
Project's homepage: http://www.tvdr.de
|
||||
Project's homepage: https://www.tvdr.de
|
||||
|
||||
Latest version available at: http://www.tvdr.de
|
||||
Latest version available at: https://www.tvdr.de
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -2,9 +2,9 @@ This is a "plugin" for the Video Disk Recorder (VDR).
|
||||
|
||||
Written by: Klaus Schmidinger <vdr@tvdr.de>
|
||||
|
||||
Project's homepage: http://www.tvdr.de
|
||||
Project's homepage: https://www.tvdr.de
|
||||
|
||||
Latest version available at: http://www.tvdr.de
|
||||
Latest version available at: https://www.tvdr.de
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -2,9 +2,9 @@ This is a "plugin" for the Video Disk Recorder (VDR).
|
||||
|
||||
Written by: Klaus Schmidinger <vdr@tvdr.de>
|
||||
|
||||
Project's homepage: http://www.tvdr.de
|
||||
Project's homepage: https://www.tvdr.de
|
||||
|
||||
Latest version available at: http://www.tvdr.de
|
||||
Latest version available at: https://www.tvdr.de
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -2,9 +2,9 @@ This is a "plugin" for the Video Disk Recorder (VDR).
|
||||
|
||||
Written by: Udo Richter <udo_richter@gmx.de>
|
||||
|
||||
Project's homepage: http://www.tvdr.de
|
||||
Project's homepage: https://www.tvdr.de
|
||||
|
||||
Latest version available at: http://www.tvdr.de
|
||||
Latest version available at: https://www.tvdr.de
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -2,9 +2,9 @@ This is a "plugin" for the Video Disk Recorder (VDR).
|
||||
|
||||
Written by: Klaus Schmidinger <vdr@tvdr.de>
|
||||
|
||||
Project's homepage: http://www.tvdr.de
|
||||
Project's homepage: https://www.tvdr.de
|
||||
|
||||
Latest version available at: http://www.tvdr.de
|
||||
Latest version available at: https://www.tvdr.de
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -76,3 +76,10 @@ VDR Plugin 'status' Revision History
|
||||
2021-12-27: Version 2.6.0
|
||||
|
||||
- Official release.
|
||||
|
||||
2025-02-10: Version 2.6.1
|
||||
|
||||
- Added cStatus::OsdItem2().
|
||||
- Activated logging of OsdItem2().
|
||||
- Added cStatus::OsdCurrentItem2().
|
||||
- Added cStatus::OsdStatusMessage2().
|
||||
|
@ -2,9 +2,9 @@ This is a "plugin" for the Video Disk Recorder (VDR).
|
||||
|
||||
Written by: Klaus Schmidinger <vdr@tvdr.de>
|
||||
|
||||
Project's homepage: http://www.tvdr.de
|
||||
Project's homepage: https://www.tvdr.de
|
||||
|
||||
Latest version available at: http://www.tvdr.de
|
||||
Latest version available at: https://www.tvdr.de
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -3,13 +3,13 @@
|
||||
*
|
||||
* See the README file for copyright information and how to reach the author.
|
||||
*
|
||||
* $Id: status.c 4.1 2018/04/10 13:01:03 kls Exp $
|
||||
* $Id: status.c 5.4 2025/02/12 21:18:53 kls Exp $
|
||||
*/
|
||||
|
||||
#include <vdr/plugin.h>
|
||||
#include <vdr/status.h>
|
||||
|
||||
static const char *VERSION = "2.4.0";
|
||||
static const char *VERSION = "2.6.1";
|
||||
static const char *DESCRIPTION = "Status monitor test";
|
||||
static const char *MAINMENUENTRY = NULL;
|
||||
|
||||
@ -27,10 +27,10 @@ protected:
|
||||
virtual void SetSubtitleTrack(int Index, const char * const *Tracks);
|
||||
virtual void OsdClear(void);
|
||||
virtual void OsdTitle(const char *Title);
|
||||
virtual void OsdStatusMessage(const char *Message);
|
||||
virtual void OsdStatusMessage2(eMessageType Type, const char *Message);
|
||||
virtual void OsdHelpKeys(const char *Red, const char *Green, const char *Yellow, const char *Blue);
|
||||
virtual void OsdItem(const char *Text, int Index);
|
||||
virtual void OsdCurrentItem(const char *Text);
|
||||
virtual void OsdItem2(const char *Text, int Index, bool Selectable);
|
||||
virtual void OsdCurrentItem2(const char *Text, int Index);
|
||||
virtual void OsdTextItem(const char *Text, bool Scroll);
|
||||
virtual void OsdChannel(const char *Text);
|
||||
virtual void OsdProgramme(time_t PresentTime, const char *PresentTitle, const char *PresentSubtitle, time_t FollowingTime, const char *FollowingTitle, const char *FollowingSubtitle);
|
||||
@ -86,9 +86,9 @@ void cStatusTest::OsdTitle(const char *Title)
|
||||
dsyslog("status: cStatusTest::OsdTitle '%s'", Title);
|
||||
}
|
||||
|
||||
void cStatusTest::OsdStatusMessage(const char *Message)
|
||||
void cStatusTest::OsdStatusMessage2(eMessageType Type, const char *Message)
|
||||
{
|
||||
dsyslog("status: cStatusTest::OsdStatusMessage '%s'", Message);
|
||||
dsyslog("status: cStatusTest::OsdStatusMessage2 %d '%s'", Type, Message);
|
||||
}
|
||||
|
||||
void cStatusTest::OsdHelpKeys(const char *Red, const char *Green, const char *Yellow, const char *Blue)
|
||||
@ -96,14 +96,14 @@ void cStatusTest::OsdHelpKeys(const char *Red, const char *Green, const char *Ye
|
||||
dsyslog("status: cStatusTest::OsdHelpKeys %s - %s - %s - %s", Red, Green, Yellow, Blue);
|
||||
}
|
||||
|
||||
void cStatusTest::OsdItem(const char *Text, int Index)
|
||||
void cStatusTest::OsdItem2(const char *Text, int Index, bool Selected)
|
||||
{
|
||||
//dsyslog("status: cStatusTest::OsdItem %s %d", Text, Index);
|
||||
dsyslog("status: cStatusTest::OsdItem2 %s %d %d", Text, Index, Selected);
|
||||
}
|
||||
|
||||
void cStatusTest::OsdCurrentItem(const char *Text)
|
||||
void cStatusTest::OsdCurrentItem2(const char *Text, int Index)
|
||||
{
|
||||
dsyslog("status: cStatusTest::OsdCurrentItem %s", Text);
|
||||
dsyslog("status: cStatusTest::OsdCurrentItem %s %d", Text, Index);
|
||||
}
|
||||
|
||||
void cStatusTest::OsdTextItem(const char *Text, bool Scroll)
|
||||
|
@ -2,9 +2,9 @@ This is a "plugin" for the Video Disk Recorder (VDR).
|
||||
|
||||
Written by: Klaus Schmidinger <Klaus.Schmidinger@tvdr.de>
|
||||
|
||||
Project's homepage: http://www.tvdr.de
|
||||
Project's homepage: https://www.tvdr.de
|
||||
|
||||
Latest version available at: http://www.tvdr.de
|
||||
Latest version available at: https://www.tvdr.de
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
4
README
4
README
@ -4,7 +4,7 @@ Video Disk Recorder ('VDR')
|
||||
These files contain the source code of the "Video Disk Recorder",
|
||||
which is based on the DVB driver of the LinuxTV project (http://linuxtv.org).
|
||||
For details about the "Video Disk Recorder" project please
|
||||
refer to http://www.tvdr.de.
|
||||
refer to https://www.tvdr.de.
|
||||
|
||||
Please see the INSTALL file for details on how to install
|
||||
this program on your computer.
|
||||
@ -33,7 +33,7 @@ the ones in this system, but here we have the full source code
|
||||
and can modify the menus in whatever way desired.
|
||||
|
||||
If you actually use VDR, please add yourself to the "VDR User Counter"
|
||||
at http://www.tvdr.de/counter.htm. You can also like VDR on facebook
|
||||
at https://www.tvdr.de/counter.htm. You can also like VDR on facebook
|
||||
at https://www.facebook.com/VideoDiskRecorder.
|
||||
|
||||
|
||||
|
@ -10,7 +10,7 @@ Plugins:
|
||||
- Implemented a universal plugin interface. See the file PLUGINS.html
|
||||
for a detailed description. The man page vdr(1) describes the new options '-L'
|
||||
and '-P' used to load plugins.
|
||||
See http://www.tvdr.de/plugins.htm for a list of available plugins.
|
||||
See https://www.tvdr.de/plugins.htm for a list of available plugins.
|
||||
- Rearranged the remote control key handling to allow plugins to implement
|
||||
additional types of remote controls (see PLUGINS.html, section "Remote Control").
|
||||
The previously used files 'keys.conf' and 'keys-pc.conf' have been replaced
|
||||
|
10
config.h
10
config.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: config.h 5.23 2024/09/27 09:15:33 kls Exp $
|
||||
* $Id: config.h 5.26 2025/02/26 10:35:03 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __CONFIG_H
|
||||
@ -22,13 +22,13 @@
|
||||
|
||||
// VDR's own version number:
|
||||
|
||||
#define VDRVERSION "2.7.2"
|
||||
#define VDRVERSNUM 20702 // Version * 10000 + Major * 100 + Minor
|
||||
#define VDRVERSION "2.7.4"
|
||||
#define VDRVERSNUM 20704 // Version * 10000 + Major * 100 + Minor
|
||||
|
||||
// The plugin API's version number:
|
||||
|
||||
#define APIVERSION "5"
|
||||
#define APIVERSNUM 30005
|
||||
#define APIVERSION "6"
|
||||
#define APIVERSNUM 30006
|
||||
|
||||
// When loading plugins, VDR searches files by their APIVERSION, which
|
||||
// is different from VDRVERSION. APIVERSION is a plain number, incremented
|
||||
|
9
cutter.c
9
cutter.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: cutter.c 5.3 2024/09/20 21:34:18 kls Exp $
|
||||
* $Id: cutter.c 5.4 2025/01/10 13:12:04 kls Exp $
|
||||
*/
|
||||
|
||||
#include "cutter.h"
|
||||
@ -623,8 +623,11 @@ void cCuttingThread::HandleErrors(bool Force)
|
||||
Force = true;
|
||||
}
|
||||
if (Force) {
|
||||
LOCK_RECORDINGS_WRITE;
|
||||
Recordings->UpdateByName(editedRecordingName);
|
||||
cStateKey StateKey;
|
||||
if (cRecordings *Recordings = cRecordings::GetRecordingsWrite(StateKey, 1)) {
|
||||
Recordings->UpdateByName(editedRecordingName);
|
||||
StateKey.Remove();
|
||||
}
|
||||
}
|
||||
lastErrorHandling = time(NULL);
|
||||
}
|
||||
|
33
dvbplayer.c
33
dvbplayer.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: dvbplayer.c 5.4 2024/09/19 09:49:02 kls Exp $
|
||||
* $Id: dvbplayer.c 5.7 2025/02/19 15:39:16 kls Exp $
|
||||
*/
|
||||
|
||||
#include "dvbplayer.h"
|
||||
@ -36,7 +36,7 @@ public:
|
||||
bool IsEmpty(void);
|
||||
void Put(uint32_t Pts, int Index, bool Independent);
|
||||
int FindIndex(uint32_t Pts);
|
||||
int FindFrameNumber(uint32_t Pts);
|
||||
int FindFrameNumber(uint32_t Pts, bool Forward);
|
||||
};
|
||||
|
||||
cPtsIndex::cPtsIndex(void)
|
||||
@ -90,30 +90,30 @@ int cPtsIndex::FindIndex(uint32_t Pts)
|
||||
return Index;
|
||||
}
|
||||
|
||||
int cPtsIndex::FindFrameNumber(uint32_t Pts)
|
||||
int cPtsIndex::FindFrameNumber(uint32_t Pts, bool Forward)
|
||||
{
|
||||
if (!Forward)
|
||||
return FindIndex(Pts); // there are only I frames in backward
|
||||
cMutexLock MutexLock(&mutex);
|
||||
if (w == r)
|
||||
return lastFound; // replay always starts at an I frame
|
||||
bool Valid = false;
|
||||
int d;
|
||||
int FrameNumber = 0;
|
||||
int UnplayedIFrame = 2; // GOPs may intersect, so we're looping until we found two unplayed I frames
|
||||
int UnplayedIFrame = 2; // GOPs may intersect, so we loop until we processed a complete unplayed GOP
|
||||
for (int i = r; i != w && UnplayedIFrame; ) {
|
||||
d = Pts - pi[i].pts;
|
||||
if (d > 0x7FFFFFFF)
|
||||
d = 0xFFFFFFFF - d; // handle rollover
|
||||
if (d > 0) {
|
||||
int32_t d = int32_t(Pts - pi[i].pts); // typecast handles rollover
|
||||
if (d >= 0) {
|
||||
if (pi[i].independent) {
|
||||
FrameNumber = pi[i].index; // an I frame's index represents its frame number
|
||||
Valid = true;
|
||||
if (d == 0)
|
||||
UnplayedIFrame = 1; // if Pts is at an I frame we only need to check up to the next I frame
|
||||
}
|
||||
else
|
||||
FrameNumber++; // for every played non-I frame, increase frame number
|
||||
}
|
||||
else
|
||||
if (pi[i].independent)
|
||||
--UnplayedIFrame;
|
||||
else if (pi[i].independent)
|
||||
--UnplayedIFrame;
|
||||
if (++i >= PTSINDEX_ENTRIES)
|
||||
i = 0;
|
||||
}
|
||||
@ -793,15 +793,17 @@ void cDvbPlayer::Forward(void)
|
||||
Pause();
|
||||
break;
|
||||
}
|
||||
Empty();
|
||||
// run into pmPause
|
||||
case pmStill:
|
||||
case pmPause:
|
||||
case pmPause: {
|
||||
LOCK_THREAD;
|
||||
Empty();
|
||||
DeviceMute();
|
||||
playMode = pmSlow;
|
||||
playDir = pdForward;
|
||||
trickSpeed = NORMAL_SPEED;
|
||||
TrickSpeed(Setup.MultiSpeedMode ? -1 : -MAX_SPEEDS);
|
||||
}
|
||||
break;
|
||||
default: esyslog("ERROR: unknown playMode %d (%s)", playMode, __FUNCTION__);
|
||||
}
|
||||
@ -842,7 +844,6 @@ void cDvbPlayer::Backward(void)
|
||||
Pause();
|
||||
break;
|
||||
}
|
||||
Empty();
|
||||
// run into pmPause
|
||||
case pmStill:
|
||||
case pmPause: {
|
||||
@ -967,7 +968,7 @@ bool cDvbPlayer::GetIndex(int &Current, int &Total, bool SnapToIFrame)
|
||||
bool cDvbPlayer::GetFrameNumber(int &Current, int &Total)
|
||||
{
|
||||
if (index) {
|
||||
Current = ptsIndex.FindFrameNumber(DeviceGetSTC());
|
||||
Current = ptsIndex.FindFrameNumber(DeviceGetSTC(), playDir == pdForward);
|
||||
Total = index->Last();
|
||||
return true;
|
||||
}
|
||||
|
18
epg.c
18
epg.c
@ -7,7 +7,7 @@
|
||||
* Original version (as used in VDR before 1.3.0) written by
|
||||
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
|
||||
*
|
||||
* $Id: epg.c 5.11 2024/09/26 19:25:41 kls Exp $
|
||||
* $Id: epg.c 5.13 2024/11/30 14:30:46 kls Exp $
|
||||
*/
|
||||
|
||||
#include "epg.h"
|
||||
@ -303,7 +303,7 @@ const char *cEvent::ContentToString(uchar Content)
|
||||
case 0x01: return tr("Content$News/Weather Report");
|
||||
case 0x02: return tr("Content$News Magazine");
|
||||
case 0x03: return tr("Content$Documentary");
|
||||
case 0x04: return tr("Content$Discussion/Inverview/Debate");
|
||||
case 0x04: return tr("Content$Discussion/Interview/Debate");
|
||||
}
|
||||
break;
|
||||
case ecgShow:
|
||||
@ -349,7 +349,7 @@ const char *cEvent::ContentToString(uchar Content)
|
||||
case 0x00: return tr("Content$Music/Ballet/Dance");
|
||||
case 0x01: return tr("Content$Rock/Pop");
|
||||
case 0x02: return tr("Content$Serious/Classical Music");
|
||||
case 0x03: return tr("Content$Folk/Tradional Music");
|
||||
case 0x03: return tr("Content$Folk/Traditional Music");
|
||||
case 0x04: return tr("Content$Jazz");
|
||||
case 0x05: return tr("Content$Musical/Opera");
|
||||
case 0x06: return tr("Content$Ballet");
|
||||
@ -1030,18 +1030,6 @@ const cEvent *cSchedule::GetFollowingEvent(void) const
|
||||
return p;
|
||||
}
|
||||
|
||||
#if DEPRECATED_SCHEDULE_GET_EVENT
|
||||
const cEvent *cSchedule::GetEvent(tEventID EventID, time_t StartTime) const
|
||||
{
|
||||
// Returns the event info with the given StartTime or, if no actual StartTime
|
||||
// is given, the one with the given EventID.
|
||||
if (StartTime > 0) // 'StartTime < 0' is apparently used with NVOD channels
|
||||
return eventsHashStartTime.Get(StartTime);
|
||||
else
|
||||
return eventsHashID.Get(EventID);
|
||||
}
|
||||
#endif
|
||||
|
||||
const cEvent *cSchedule::GetEventById(tEventID EventID) const
|
||||
{
|
||||
return eventsHashID.Get(EventID);
|
||||
|
9
epg.h
9
epg.h
@ -7,7 +7,7 @@
|
||||
* Original version (as used in VDR before 1.3.0) written by
|
||||
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
|
||||
*
|
||||
* $Id: epg.h 5.6 2024/09/14 14:17:12 kls Exp $
|
||||
* $Id: epg.h 5.8 2024/10/13 09:47:18 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __EPG_H
|
||||
@ -186,13 +186,6 @@ public:
|
||||
const cList<cEvent> *Events(void) const { return &events; }
|
||||
const cEvent *GetPresentEvent(void) const;
|
||||
const cEvent *GetFollowingEvent(void) const;
|
||||
#ifndef DEPRECATED_SCHEDULE_GET_EVENT
|
||||
#define DEPRECATED_SCHEDULE_GET_EVENT 0
|
||||
#endif
|
||||
#if DEPRECATED_SCHEDULE_GET_EVENT
|
||||
[[deprecated("see HISTORY, version 2.5.2")]]
|
||||
const cEvent *GetEvent(tEventID EventID, time_t StartTime = 0) const;
|
||||
#endif
|
||||
const cEvent *GetEventById(tEventID EventID) const;
|
||||
const cEvent *GetEventByTime(time_t StartTime) const;
|
||||
const cEvent *GetEventAround(time_t Time) const;
|
||||
|
31
filter.c
31
filter.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: filter.c 5.1 2021/03/16 15:10:54 kls Exp $
|
||||
* $Id: filter.c 5.2 2024/10/13 09:47:18 kls Exp $
|
||||
*/
|
||||
|
||||
#include "filter.h"
|
||||
@ -73,35 +73,6 @@ bool cSectionSyncer::Processed(int SectionNumber, int LastSectionNumber, int Seg
|
||||
return complete;
|
||||
}
|
||||
|
||||
#if DEPRECATED_SECTIONSYNCER_SYNC_REPEAT
|
||||
void cSectionSyncer::Repeat(void)
|
||||
{
|
||||
SetSectionFlag(currentSection, false);
|
||||
synced = false;
|
||||
complete = false;
|
||||
}
|
||||
|
||||
bool cSectionSyncer::Sync(uchar Version, int Number, int LastNumber)
|
||||
{
|
||||
if (Version != currentVersion) {
|
||||
Reset();
|
||||
currentVersion = Version;
|
||||
}
|
||||
if (!synced) {
|
||||
if (Number != 0)
|
||||
return false;
|
||||
else
|
||||
synced = true;
|
||||
}
|
||||
currentSection = Number;
|
||||
bool Result = !GetSectionFlag(Number);
|
||||
SetSectionFlag(Number, true);
|
||||
if (Number == LastNumber)
|
||||
complete = true;
|
||||
return Result;
|
||||
}
|
||||
#endif
|
||||
|
||||
// --- cFilterData -----------------------------------------------------------
|
||||
|
||||
cFilterData::cFilterData(void)
|
||||
|
12
filter.h
12
filter.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: filter.h 5.3 2024/09/09 22:15:59 kls Exp $
|
||||
* $Id: filter.h 5.5 2024/10/13 09:47:18 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __FILTER_H
|
||||
@ -13,10 +13,6 @@
|
||||
#include <sys/types.h>
|
||||
#include "tools.h"
|
||||
|
||||
#ifndef DEPRECATED_SECTIONSYNCER_SYNC_REPEAT
|
||||
#define DEPRECATED_SECTIONSYNCER_SYNC_REPEAT 0
|
||||
#endif
|
||||
|
||||
class cSectionSyncer {
|
||||
private:
|
||||
int currentVersion;
|
||||
@ -51,12 +47,6 @@ public:
|
||||
///< Returns true if all sections have been processed.
|
||||
bool Complete(void) { return complete; }
|
||||
///< Returns true if all sections have been processed.
|
||||
#if DEPRECATED_SECTIONSYNCER_SYNC_REPEAT
|
||||
[[deprecated("see HISTORY, version 2.5.2")]]
|
||||
void Repeat(void);
|
||||
[[deprecated("see HISTORY, version 2.5.2")]]
|
||||
bool Sync(uchar Version, int Number, int LastNumber);
|
||||
#endif
|
||||
};
|
||||
|
||||
class cSectionSyncerRandom : public cSectionSyncer {
|
||||
|
4
font.c
4
font.c
@ -6,7 +6,7 @@
|
||||
*
|
||||
* BiDi support by Osama Alrawab <alrawab@hotmail.com> @2008 Tripoli-Libya.
|
||||
*
|
||||
* $Id: font.c 5.2 2022/12/06 12:30:13 kls Exp $
|
||||
* $Id: font.c 5.3 2025/02/17 11:13:13 kls Exp $
|
||||
*/
|
||||
|
||||
#include "font.h"
|
||||
@ -618,7 +618,7 @@ void cTextWrapper::Set(const char *Text, const cFont *Font, int Width)
|
||||
}
|
||||
}
|
||||
w += cw;
|
||||
if (strchr("-.,:;!?_", *p)) {
|
||||
if (strchr("-.,:;!?_~", *p)) {
|
||||
Delim = p;
|
||||
Blank = NULL;
|
||||
}
|
||||
|
108
menu.c
108
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 5.17 2024/09/19 09:49:02 kls Exp $
|
||||
* $Id: menu.c 5.23 2025/02/25 15:53:43 kls Exp $
|
||||
*/
|
||||
|
||||
#include "menu.h"
|
||||
@ -342,6 +342,7 @@ void cMenuChannelItem::Set(void)
|
||||
|
||||
void cMenuChannelItem::SetMenuItem(cSkinDisplayMenu *DisplayMenu, int Index, bool Current, bool Selectable)
|
||||
{
|
||||
LOCK_CHANNELS_READ;
|
||||
if (!DisplayMenu->SetItemChannel(channel, Index, Current, Selectable, sortMode == csmProvider))
|
||||
DisplayMenu->SetItem(Text(), Index, Current, Selectable);
|
||||
}
|
||||
@ -443,8 +444,9 @@ eOSState cMenuChannels::Number(eKeys Key)
|
||||
number = number * 10 + Key - k0;
|
||||
for (cMenuChannelItem *ci = (cMenuChannelItem *)First(); ci; ci = (cMenuChannelItem *)ci->Next()) {
|
||||
if (!ci->Channel()->GroupSep() && ci->Channel()->Number() == number) {
|
||||
DisplayCurrent(false);
|
||||
SetCurrent(ci);
|
||||
Display();
|
||||
DisplayCurrent(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1263,6 +1265,7 @@ void cMenuTimerItem::Set(void)
|
||||
}
|
||||
const char *File = timer->Pattern();
|
||||
if (!*File) {
|
||||
LOCK_SCHEDULES_READ;
|
||||
if (timer->HasFlags(tfSpawned) && timer->Event() && timer->Event()->Title())
|
||||
File = timer->Event()->Title();
|
||||
else {
|
||||
@ -1291,6 +1294,7 @@ void cMenuTimerItem::Set(void)
|
||||
|
||||
void cMenuTimerItem::SetMenuItem(cSkinDisplayMenu *DisplayMenu, int Index, bool Current, bool Selectable)
|
||||
{
|
||||
LOCK_TIMERS_READ;
|
||||
if (!DisplayMenu->SetItemTimer(timer, Index, Current, Selectable))
|
||||
DisplayMenu->SetItem(Text(), Index, Current, Selectable);
|
||||
}
|
||||
@ -1334,12 +1338,15 @@ void cMenuTimers::Set(void)
|
||||
const cTimer *CurrentTimer = GetTimer();
|
||||
cMenuTimerItem *CurrentItem = NULL;
|
||||
Clear();
|
||||
for (const cTimer *Timer = Timers->First(); Timer; Timer = Timers->Next(Timer)) {
|
||||
cMenuTimerItem *Item = new cMenuTimerItem(Timer);
|
||||
Add(Item);
|
||||
if (CurrentTimer && Timer->Id() == CurrentTimer->Id() && (!Timer->Remote() && !CurrentTimer->Remote() || Timer->Remote() && CurrentTimer->Remote() && strcmp(Timer->Remote(), CurrentTimer->Remote()) == 0))
|
||||
CurrentItem = Item;
|
||||
}
|
||||
{
|
||||
LOCK_SCHEDULES_READ;
|
||||
for (const cTimer *Timer = Timers->First(); Timer; Timer = Timers->Next(Timer)) {
|
||||
cMenuTimerItem *Item = new cMenuTimerItem(Timer);
|
||||
Add(Item);
|
||||
if (CurrentTimer && Timer->Id() == CurrentTimer->Id() && (!Timer->Remote() && !CurrentTimer->Remote() || Timer->Remote() && CurrentTimer->Remote() && strcmp(Timer->Remote(), CurrentTimer->Remote()) == 0))
|
||||
CurrentItem = Item;
|
||||
}
|
||||
}
|
||||
Sort();
|
||||
SetCurrent(CurrentItem ? CurrentItem : First());
|
||||
SetHelpKeys();
|
||||
@ -1454,6 +1461,7 @@ eOSState cMenuTimers::Info(void)
|
||||
return osContinue;
|
||||
LOCK_TIMERS_READ;
|
||||
LOCK_CHANNELS_READ;
|
||||
LOCK_SCHEDULES_READ;
|
||||
cTimer *Timer = GetTimer();
|
||||
if (Timer && Timer->Event())
|
||||
return AddSubMenu(new cMenuEvent(Timers, Channels, Timer->Event()));
|
||||
@ -1513,6 +1521,7 @@ cMenuEvent::cMenuEvent(const cTimers *Timers, const cChannels *Channels, const c
|
||||
|
||||
void cMenuEvent::Display(void)
|
||||
{
|
||||
LOCK_SCHEDULES_READ;
|
||||
cOsdMenu::Display();
|
||||
DisplayMenu()->SetEvent(event);
|
||||
if (event->Description())
|
||||
@ -1599,6 +1608,8 @@ static const char *TimerMatchChars = " tT iI";
|
||||
|
||||
bool cMenuScheduleItem::Update(const cTimers *Timers, bool Force)
|
||||
{
|
||||
LOCK_CHANNELS_READ;
|
||||
LOCK_SCHEDULES_READ;
|
||||
eTimerMatch OldTimerMatch = timerMatch;
|
||||
bool OldTimerActive = timerActive;
|
||||
const cTimer *Timer = Timers->GetMatch(event, &timerMatch);
|
||||
@ -1626,6 +1637,8 @@ bool cMenuScheduleItem::Update(const cTimers *Timers, bool Force)
|
||||
|
||||
void cMenuScheduleItem::SetMenuItem(cSkinDisplayMenu *DisplayMenu, int Index, bool Current, bool Selectable)
|
||||
{
|
||||
LOCK_CHANNELS_READ;
|
||||
LOCK_SCHEDULES_READ;
|
||||
if (!DisplayMenu->SetItemEvent(event, Index, Current, Selectable, channel, withDate, timerMatch, timerActive))
|
||||
DisplayMenu->SetItem(Text(), Index, Current, Selectable);
|
||||
}
|
||||
@ -1671,7 +1684,6 @@ cMenuWhatsOn::cMenuWhatsOn(const cTimers *Timers, const cChannels *Channels, con
|
||||
}
|
||||
}
|
||||
currentChannel = CurrentChannelNr;
|
||||
Display();
|
||||
SetHelpKeys(Channels);
|
||||
}
|
||||
|
||||
@ -1772,10 +1784,8 @@ eOSState cMenuWhatsOn::Record(void)
|
||||
if (HasSubMenu())
|
||||
CloseSubMenu();
|
||||
}
|
||||
if (Update()) {
|
||||
LOCK_SCHEDULES_READ;
|
||||
if (Update())
|
||||
Display();
|
||||
}
|
||||
LOCK_CHANNELS_READ;
|
||||
SetHelpKeys(Channels);
|
||||
return osContinue;
|
||||
@ -1795,6 +1805,7 @@ eOSState cMenuWhatsOn::ProcessKey(eKeys Key)
|
||||
case kGreen: {
|
||||
cMenuScheduleItem *mi = (cMenuScheduleItem *)Get(Current());
|
||||
if (mi) {
|
||||
LOCK_CHANNELS_READ;
|
||||
scheduleEvent = mi->event;
|
||||
currentChannel = mi->channel->Number();
|
||||
}
|
||||
@ -1807,14 +1818,12 @@ eOSState cMenuWhatsOn::ProcessKey(eKeys Key)
|
||||
case kChanUp:
|
||||
case kChanDn|k_Repeat:
|
||||
case kChanDn: if (!HasSubMenu()) {
|
||||
LOCK_CHANNELS_READ;
|
||||
for (cOsdItem *item = First(); item; item = Next(item)) {
|
||||
if (((cMenuScheduleItem *)item)->channel->Number() == cDevice::CurrentChannel()) {
|
||||
DisplayCurrent(false);
|
||||
SetCurrent(item);
|
||||
{
|
||||
LOCK_SCHEDULES_READ;
|
||||
Display();
|
||||
}
|
||||
LOCK_CHANNELS_READ;
|
||||
DisplayCurrent(true);
|
||||
SetHelpKeys(Channels);
|
||||
break;
|
||||
}
|
||||
@ -1832,10 +1841,8 @@ eOSState cMenuWhatsOn::ProcessKey(eKeys Key)
|
||||
}
|
||||
}
|
||||
else if (!HasSubMenu()) {
|
||||
if (HadSubMenu && Update()) {
|
||||
LOCK_SCHEDULES_READ;
|
||||
if (HadSubMenu && Update())
|
||||
Display();
|
||||
}
|
||||
if (Key != kNone) {
|
||||
LOCK_CHANNELS_READ;
|
||||
SetHelpKeys(Channels);
|
||||
@ -2083,10 +2090,8 @@ eOSState cMenuSchedule::Record(void)
|
||||
if (HasSubMenu())
|
||||
CloseSubMenu();
|
||||
}
|
||||
if (Update()) {
|
||||
LOCK_SCHEDULES_READ;
|
||||
if (Update())
|
||||
Display();
|
||||
}
|
||||
SetHelpKeys();
|
||||
return osContinue;
|
||||
}
|
||||
@ -2180,10 +2185,8 @@ eOSState cMenuSchedule::ProcessKey(eKeys Key)
|
||||
Set(Timers, Channels, Channel, true);
|
||||
}
|
||||
}
|
||||
else if (HadSubMenu && Update()) {
|
||||
LOCK_SCHEDULES_READ;
|
||||
else if (HadSubMenu && Update())
|
||||
Display();
|
||||
}
|
||||
if (Key != kNone)
|
||||
SetHelpKeys();
|
||||
}
|
||||
@ -3042,6 +3045,7 @@ void cMenuRecordingItem::IncrementCounter(bool New)
|
||||
|
||||
void cMenuRecordingItem::SetMenuItem(cSkinDisplayMenu *DisplayMenu, int Index, bool Current, bool Selectable)
|
||||
{
|
||||
LOCK_RECORDINGS_READ;
|
||||
if (!DisplayMenu->SetItemRecording(recording, Index, Current, Selectable, level, totalEntries, newEntries))
|
||||
DisplayMenu->SetItem(Text(), Index, Current, Selectable);
|
||||
}
|
||||
@ -4666,15 +4670,16 @@ eOSState cMenuMain::ProcessKey(eKeys Key)
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
if (!HasSubMenu() && Update(HadSubMenu))
|
||||
Display();
|
||||
bool DoDisplay = Update();
|
||||
if (Key != kNone) {
|
||||
if (I18nCurrentLanguage() != osdLanguage) {
|
||||
Set();
|
||||
if (!HasSubMenu())
|
||||
Display();
|
||||
DoDisplay = true;
|
||||
}
|
||||
}
|
||||
if (DoDisplay)
|
||||
Display();
|
||||
return state;
|
||||
}
|
||||
|
||||
@ -6097,6 +6102,47 @@ void cReplayControl::MarkMove(int Frames, bool MarkRequired)
|
||||
}
|
||||
}
|
||||
|
||||
void cReplayControl::ErrorJump(bool Forward)
|
||||
{
|
||||
const cErrors *Errors = GetErrors();
|
||||
int NumErrors = Errors ? Errors->Size() : 0;
|
||||
if (NumErrors > 0) {
|
||||
int Current, Total;
|
||||
if (GetIndex(Current, Total)) {
|
||||
if (Forward) {
|
||||
int Offset = 0;
|
||||
for (int i = 0; i < NumErrors; i++) {
|
||||
int Position = Errors->At(i);
|
||||
if (Position > Current + Offset) {
|
||||
int NextIFrame = SkipFrames(Position - Current) + Offset; // this takes us to the I-frame at or right after Position
|
||||
if (NextIFrame > Position) {
|
||||
if (SkipFrames(Offset + 1) == NextIFrame) { // means Current is the I-frame right before Position
|
||||
Offset = NextIFrame - Current;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Goto(Position, true); // this takes us to the I-frame at or right before Position
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (Current < Total)
|
||||
Goto(Total, true);
|
||||
}
|
||||
else {
|
||||
for (int i = NumErrors - 1; i >= 0; i--) {
|
||||
if (Errors->At(i) < Current) {
|
||||
int Position = Errors->At(i);
|
||||
Goto(Position, true); // this takes us to the I-frame at or right before Position
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (Current > 0)
|
||||
Goto(0, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cReplayControl::EditCut(void)
|
||||
{
|
||||
if (*fileName) {
|
||||
@ -6241,6 +6287,10 @@ eOSState cReplayControl::ProcessKey(eKeys Key)
|
||||
case kMarkSkipBack: MarkMove(-adaptiveSkipper.GetValue(RAWKEY(Key)), false); break;
|
||||
case kMarkSkipForward|k_Repeat:
|
||||
case kMarkSkipForward: MarkMove(+adaptiveSkipper.GetValue(RAWKEY(Key)), false); break;
|
||||
case kChanUp|k_Repeat:
|
||||
case kChanUp: ErrorJump(true); break;
|
||||
case kChanDn|k_Repeat:
|
||||
case kChanDn: ErrorJump(false); break;
|
||||
case kEditCut: EditCut(); break;
|
||||
case kEditTest: EditTest(); break;
|
||||
default: {
|
||||
|
3
menu.h
3
menu.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: menu.h 5.4 2024/09/19 09:49:02 kls Exp $
|
||||
* $Id: menu.h 5.5 2024/10/11 14:10:50 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __MENU_H
|
||||
@ -316,6 +316,7 @@ private:
|
||||
void MarkToggle(void);
|
||||
void MarkJump(bool Forward);
|
||||
void MarkMove(int Frames, bool MarkRequired);
|
||||
void ErrorJump(bool Forward);
|
||||
void EditCut(void);
|
||||
void EditTest(void);
|
||||
public:
|
||||
|
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: menuitems.c 5.2 2024/07/13 09:12:18 kls Exp $
|
||||
* $Id: menuitems.c 5.3 2025/01/29 10:20:17 kls Exp $
|
||||
*/
|
||||
|
||||
#include "menuitems.h"
|
||||
@ -38,7 +38,6 @@ void cMenuEditItem::SetValue(const char *Value)
|
||||
{
|
||||
cString buffer = cString::sprintf("%s:\t%s", name, Value);
|
||||
SetText(buffer);
|
||||
cStatus::MsgOsdCurrentItem(buffer);
|
||||
}
|
||||
|
||||
void cMenuEditItem::SetHelp(const char *Red, const char *Green, const char *Yellow, const char *Blue)
|
||||
|
@ -12,7 +12,7 @@
|
||||
# See the main source file 'vdr.c' for copyright information and
|
||||
# how to reach the author.
|
||||
#
|
||||
# $Id: newplugin 5.1 2021/01/02 14:32:20 kls Exp $
|
||||
# $Id: newplugin 5.2 2025/02/12 22:22:20 kls Exp $
|
||||
|
||||
$PLUGIN_NAME = $ARGV[0] || die "Usage: newplugin <name>\n";
|
||||
|
||||
@ -216,7 +216,6 @@ public:
|
||||
virtual bool Start(void);
|
||||
virtual void Stop(void);
|
||||
virtual void Housekeeping(void);
|
||||
virtual void MainThreadHook(void);
|
||||
virtual cString Active(void);
|
||||
virtual time_t WakeupTime(void);
|
||||
virtual const char *MainMenuEntry(void) { return MAINMENUENTRY; }
|
||||
@ -274,12 +273,6 @@ void cPlugin${PLUGIN_CLASS}::Housekeeping(void)
|
||||
// Perform any cleanup or other regular tasks.
|
||||
}
|
||||
|
||||
void cPlugin${PLUGIN_CLASS}::MainThreadHook(void)
|
||||
{
|
||||
// Perform actions in the context of the main program thread.
|
||||
// WARNING: Use with great care - see PLUGINS.html!
|
||||
}
|
||||
|
||||
cString cPlugin${PLUGIN_CLASS}::Active(void)
|
||||
{
|
||||
// Return a message string if shutdown should be postponed
|
||||
|
82
osdbase.c
82
osdbase.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: osdbase.c 5.1 2024/01/19 12:10:47 kls Exp $
|
||||
* $Id: osdbase.c 5.9 2025/02/17 10:49:10 kls Exp $
|
||||
*/
|
||||
|
||||
#include "osdbase.h"
|
||||
@ -78,12 +78,16 @@ void cOsdObject::Show(void)
|
||||
cSkinDisplayMenu *cOsdMenu::displayMenu = NULL;
|
||||
int cOsdMenu::displayMenuCount = 0;
|
||||
int cOsdMenu::osdState = 0;
|
||||
cOsdMenu *cOsdMenu::topMenu = NULL;
|
||||
|
||||
cOsdMenu::cOsdMenu(const char *Title, int c0, int c1, int c2, int c3, int c4)
|
||||
{
|
||||
isMenu = true;
|
||||
digit = 0;
|
||||
hasHotkeys = false;
|
||||
if (!topMenu)
|
||||
topMenu = this;
|
||||
active = this == topMenu;
|
||||
displayMenuItems = 0;
|
||||
title = NULL;
|
||||
menuCategory = mcUnknown;
|
||||
@ -93,6 +97,7 @@ cOsdMenu::cOsdMenu(const char *Title, int c0, int c1, int c2, int c3, int c4)
|
||||
SetCols(c0, c1, c2, c3, c4);
|
||||
first = 0;
|
||||
lastOffset = -1;
|
||||
conveyStatus = true;
|
||||
current = marked = -1;
|
||||
subMenu = NULL;
|
||||
helpRed = helpGreen = helpYellow = helpBlue = NULL;
|
||||
@ -113,6 +118,8 @@ cOsdMenu::~cOsdMenu()
|
||||
cStatus::MsgOsdClear();
|
||||
if (!--displayMenuCount)
|
||||
DELETENULL(displayMenu);
|
||||
if (this == topMenu)
|
||||
topMenu = NULL;
|
||||
}
|
||||
|
||||
void cOsdMenu::SetMenuCategory(eMenuCategory MenuCategory)
|
||||
@ -125,6 +132,11 @@ void cOsdMenu::SetMenuSortMode(eMenuSortMode MenuSortMode)
|
||||
menuSortMode = MenuSortMode;
|
||||
}
|
||||
|
||||
void cOsdMenu::SetActive(bool Active)
|
||||
{
|
||||
active = Active;
|
||||
}
|
||||
|
||||
void cOsdMenu::SetDisplayMenu(void)
|
||||
{
|
||||
if (displayMenu) {
|
||||
@ -169,6 +181,7 @@ void cOsdMenu::SetStatus(const char *s)
|
||||
free(status);
|
||||
status = s ? strdup(s) : NULL;
|
||||
displayMenu->SetMessage(mtStatus, s);
|
||||
cStatus::MsgOsdStatusMessage(mtStatus, s);
|
||||
}
|
||||
|
||||
void cOsdMenu::SetTitle(const char *Title)
|
||||
@ -181,7 +194,8 @@ void cOsdMenu::DisplayHelp(bool Force)
|
||||
{
|
||||
if (!helpDisplayed || Force) {
|
||||
displayMenu->SetButtons(helpRed, helpGreen, helpYellow, helpBlue);
|
||||
cStatus::MsgOsdHelpKeys(helpRed, helpGreen, helpYellow, helpBlue);
|
||||
if (conveyStatus)
|
||||
cStatus::MsgOsdHelpKeys(helpRed, helpGreen, helpYellow, helpBlue);
|
||||
helpDisplayed = true;
|
||||
}
|
||||
}
|
||||
@ -224,17 +238,28 @@ void cOsdMenu::Ins(cOsdItem *Item, bool Current, cOsdItem *Before)
|
||||
current = Item->Index();
|
||||
}
|
||||
|
||||
void cOsdMenu::DisplayNoStatus(void)
|
||||
{
|
||||
conveyStatus = false;
|
||||
Display();
|
||||
conveyStatus = true;
|
||||
}
|
||||
|
||||
void cOsdMenu::Display(void)
|
||||
{
|
||||
if (subMenu) {
|
||||
subMenu->Display();
|
||||
return;
|
||||
}
|
||||
if (!active)
|
||||
return;
|
||||
if (cOsdProvider::OsdSizeChanged(osdState))
|
||||
SetDisplayMenu();
|
||||
displayMenu->SetMessage(mtStatus, NULL);
|
||||
cStatus::MsgOsdStatusMessage(mtStatus, NULL);
|
||||
displayMenu->Clear();
|
||||
cStatus::MsgOsdClear();
|
||||
if (conveyStatus)
|
||||
cStatus::MsgOsdClear();
|
||||
if (menuCategory != displayMenu->MenuCategory())
|
||||
displayMenu->SetMenuCategory(menuCategory);
|
||||
displayMenu->SetMenuSortMode(menuSortMode);
|
||||
@ -242,13 +267,15 @@ void cOsdMenu::Display(void)
|
||||
displayMenuItems = displayMenu->MaxItems();
|
||||
displayMenu->SetTabs(cols[0], cols[1], cols[2], cols[3], cols[4]);//XXX
|
||||
displayMenu->SetTitle(title);
|
||||
cStatus::MsgOsdTitle(title);
|
||||
if (conveyStatus)
|
||||
cStatus::MsgOsdTitle(title);
|
||||
DisplayHelp(true);
|
||||
int count = Count();
|
||||
if (count > 0) {
|
||||
int ni = 0;
|
||||
for (cOsdItem *item = First(); item; item = Next(item)) {
|
||||
cStatus::MsgOsdItem(item->Text(), ni++);
|
||||
if (conveyStatus)
|
||||
cStatus::MsgOsdItem(item->Text(), ni++, item->Selectable());
|
||||
if (current < 0 && item->Selectable())
|
||||
current = item->Index();
|
||||
}
|
||||
@ -267,16 +294,18 @@ void cOsdMenu::Display(void)
|
||||
for (cOsdItem *item = Get(first); item; item = Next(item)) {
|
||||
bool CurrentSelectable = (i == current) && item->Selectable();
|
||||
item->SetMenuItem(displayMenu, i - first, CurrentSelectable, item->Selectable());
|
||||
if (CurrentSelectable)
|
||||
cStatus::MsgOsdCurrentItem(item->Text());
|
||||
if (CurrentSelectable) // not checking conveyStatus here!
|
||||
cStatus::MsgOsdCurrentItem(item->Text(), i);
|
||||
if (++n == displayMenuItems)
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
displayMenu->SetScrollbar(count, first);
|
||||
if (!isempty(status))
|
||||
if (!isempty(status)) {
|
||||
displayMenu->SetMessage(mtStatus, status);
|
||||
cStatus::MsgOsdStatusMessage(mtStatus, status);
|
||||
}
|
||||
}
|
||||
|
||||
void cOsdMenu::SetCurrent(cOsdItem *Item)
|
||||
@ -299,9 +328,13 @@ void cOsdMenu::DisplayCurrent(bool Current)
|
||||
cOsdItem *item = Get(current);
|
||||
if (item) {
|
||||
item->SetMenuItem(displayMenu, current - first, Current && item->Selectable(), item->Selectable());
|
||||
if (Current && item->Selectable())
|
||||
cStatus::MsgOsdCurrentItem(item->Text());
|
||||
if (!Current)
|
||||
if (Current) {
|
||||
if (current - first >= displayMenuItems || current < first)
|
||||
DisplayNoStatus();
|
||||
else if (item->Selectable())
|
||||
cStatus::MsgOsdCurrentItem(item->Text(), current);
|
||||
}
|
||||
else
|
||||
item->SetFresh(true); // leaving the current item resets 'fresh'
|
||||
if (cMenuEditItem *MenuEditItem = dynamic_cast<cMenuEditItem *>(item)) {
|
||||
if (!MenuEditItem->DisplayHelp(Current))
|
||||
@ -321,7 +354,7 @@ void cOsdMenu::DisplayItem(cOsdItem *Item)
|
||||
bool Current = Index == current;
|
||||
Item->SetMenuItem(displayMenu, Offset, Current && Item->Selectable(), Item->Selectable());
|
||||
if (Current && Item->Selectable())
|
||||
cStatus::MsgOsdCurrentItem(Item->Text());
|
||||
cStatus::MsgOsdCurrentItem(Item->Text(), Index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -355,7 +388,7 @@ void cOsdMenu::CursorUp(void)
|
||||
if (first > 0) {
|
||||
// make non-selectable items at the beginning visible:
|
||||
first = 0;
|
||||
Display();
|
||||
DisplayNoStatus();
|
||||
return;
|
||||
}
|
||||
if (Setup.MenuScrollWrap)
|
||||
@ -371,11 +404,11 @@ void cOsdMenu::CursorUp(void)
|
||||
current = tmpCurrent;
|
||||
if (current < first) {
|
||||
first = Setup.MenuScrollPage ? max(0, current - displayMenuItems + 1) : current;
|
||||
Display();
|
||||
DisplayNoStatus();
|
||||
}
|
||||
else if (current > lastOnScreen) {
|
||||
first = max(0, current - displayMenuItems + 1);
|
||||
Display();
|
||||
DisplayNoStatus();
|
||||
}
|
||||
else
|
||||
DisplayCurrent(true);
|
||||
@ -393,7 +426,7 @@ void cOsdMenu::CursorDown(void)
|
||||
if (first < last - displayMenuItems) {
|
||||
// make non-selectable items at the end visible:
|
||||
first = last - displayMenuItems + 1;
|
||||
Display();
|
||||
DisplayNoStatus();
|
||||
return;
|
||||
}
|
||||
if (Setup.MenuScrollWrap)
|
||||
@ -411,11 +444,11 @@ void cOsdMenu::CursorDown(void)
|
||||
first = Setup.MenuScrollPage ? current : max(0, current - displayMenuItems + 1);
|
||||
if (first + displayMenuItems > last)
|
||||
first = max(0, last - displayMenuItems + 1);
|
||||
Display();
|
||||
DisplayNoStatus();
|
||||
}
|
||||
else if (current < first) {
|
||||
first = current;
|
||||
Display();
|
||||
DisplayNoStatus();
|
||||
}
|
||||
else
|
||||
DisplayCurrent(true);
|
||||
@ -448,7 +481,7 @@ void cOsdMenu::PageUp(void)
|
||||
first = current - displayMenuItems + 1;
|
||||
}
|
||||
if (current != oldCurrent || first != oldFirst)
|
||||
Display();
|
||||
DisplayNoStatus();
|
||||
else if (Setup.MenuScrollWrap)
|
||||
CursorUp();
|
||||
}
|
||||
@ -480,7 +513,7 @@ void cOsdMenu::PageDown(void)
|
||||
first = current - displayMenuItems + 1;
|
||||
}
|
||||
if (current != oldCurrent || first != oldFirst)
|
||||
Display();
|
||||
DisplayNoStatus();
|
||||
else if (Setup.MenuScrollWrap)
|
||||
CursorDown();
|
||||
}
|
||||
@ -499,9 +532,10 @@ eOSState cOsdMenu::HotKey(eKeys Key)
|
||||
const char *s = item->Text();
|
||||
if (s && (s = skipspace(s)) != NULL) {
|
||||
if (*s == Key - k1 + '1') {
|
||||
DisplayCurrent(false);
|
||||
current = item->Index();
|
||||
RefreshCurrent();
|
||||
Display();
|
||||
DisplayCurrent(true);
|
||||
cRemote::Put(kOk, true);
|
||||
break;
|
||||
}
|
||||
@ -512,8 +546,10 @@ eOSState cOsdMenu::HotKey(eKeys Key)
|
||||
|
||||
eOSState cOsdMenu::AddSubMenu(cOsdMenu *SubMenu)
|
||||
{
|
||||
SetActive(false);
|
||||
delete subMenu;
|
||||
subMenu = SubMenu;
|
||||
subMenu->SetActive(true);
|
||||
subMenu->Display();
|
||||
return osContinue; // convenience return value
|
||||
}
|
||||
@ -522,6 +558,7 @@ eOSState cOsdMenu::CloseSubMenu(bool ReDisplay)
|
||||
{
|
||||
delete subMenu;
|
||||
subMenu = NULL;
|
||||
SetActive(true);
|
||||
if (ReDisplay) {
|
||||
RefreshCurrent();
|
||||
Display();
|
||||
@ -542,7 +579,8 @@ eOSState cOsdMenu::ProcessKey(eKeys Key)
|
||||
if (marked < 0 && item) {
|
||||
eOSState state = item->ProcessKey(Key);
|
||||
if (state != osUnknown) {
|
||||
DisplayCurrent(true);
|
||||
if (Key != kNone)
|
||||
DisplayCurrent(true);
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: osdbase.h 4.5 2018/01/25 15:09:23 kls Exp $
|
||||
* $Id: osdbase.h 5.2 2025/02/17 10:49:10 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __OSDBASE_H
|
||||
@ -87,11 +87,13 @@ private:
|
||||
static cSkinDisplayMenu *displayMenu;
|
||||
static int displayMenuCount;
|
||||
static int osdState;
|
||||
static cOsdMenu *topMenu;
|
||||
int displayMenuItems;
|
||||
char *title;
|
||||
int cols[cSkinDisplayMenu::MaxTabs];
|
||||
int first, current, marked;
|
||||
int lastOffset;
|
||||
bool conveyStatus;
|
||||
eMenuCategory menuCategory;
|
||||
eMenuSortMode menuSortMode;
|
||||
eMenuOrientation menuOrientation;
|
||||
@ -101,7 +103,10 @@ private:
|
||||
char *status;
|
||||
int digit;
|
||||
bool hasHotkeys;
|
||||
bool active;
|
||||
void SetActive(bool Active);
|
||||
void DisplayHelp(bool Force = false);
|
||||
void DisplayNoStatus(void);
|
||||
protected:
|
||||
void SetDisplayMenu(void);
|
||||
cSkinDisplayMenu *DisplayMenu(void) { return displayMenu; }
|
||||
|
13
player.c
13
player.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: player.c 5.1 2024/07/16 12:33:27 kls Exp $
|
||||
* $Id: player.c 5.2 2024/10/13 09:47:18 kls Exp $
|
||||
*/
|
||||
|
||||
#include "player.h"
|
||||
@ -70,14 +70,6 @@ cString cControl::GetHeader(void)
|
||||
return "";
|
||||
}
|
||||
|
||||
#if DEPRECATED_CCONTROL
|
||||
cControl *cControl::Control(bool Hidden)
|
||||
{
|
||||
cMutexLock MutexLock(&mutex);
|
||||
return (control && (!control->hidden || Hidden)) ? control : NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
cControl *cControl::Control(cMutexLock &MutexLock, bool Hidden)
|
||||
{
|
||||
MutexLock.Lock(&mutex);
|
||||
@ -87,9 +79,8 @@ cControl *cControl::Control(cMutexLock &MutexLock, bool Hidden)
|
||||
void cControl::Launch(cControl *Control)
|
||||
{
|
||||
cMutexLock MutexLock(&mutex);
|
||||
cControl *c = control; // keeps control from pointing to uninitialized memory TODO obsolete once DEPRECATED_CCONTROL is gone
|
||||
delete control;
|
||||
control = Control;
|
||||
delete c;
|
||||
}
|
||||
|
||||
void cControl::Attach(void)
|
||||
|
14
player.h
14
player.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: player.h 5.4 2024/09/19 09:49:02 kls Exp $
|
||||
* $Id: player.h 5.6 2024/10/13 09:47:18 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __PLAYER_H
|
||||
@ -117,18 +117,6 @@ public:
|
||||
static void Launch(cControl *Control);
|
||||
static void Attach(void);
|
||||
static void Shutdown(void);
|
||||
#ifndef DEPRECATED_CCONTROL
|
||||
#define DEPRECATED_CCONTROL 0
|
||||
#endif
|
||||
#if DEPRECATED_CCONTROL
|
||||
[[deprecated("see HISTORY, version 2.4.2")]]
|
||||
static cControl *Control(bool Hidden = false);
|
||||
///< Old version of this function, for backwards compatibility with plugins.
|
||||
///< Plugins should be changed to use the new version below, which does
|
||||
///< proper locking.
|
||||
///< Use of this function may result in program crashes in case replay is
|
||||
///< stopped immediately after starting it.
|
||||
#endif
|
||||
static cControl *Control(cMutexLock &MutexLock, bool Hidden = false);
|
||||
///< Returns the current replay control (if any) in case it is currently
|
||||
///< visible. If Hidden is true, the control will be returned even if it is
|
||||
|
3
plugin.c
3
plugin.c
@ -4,9 +4,10 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: plugin.c 4.4 2020/12/16 11:54:06 kls Exp $
|
||||
* $Id: plugin.c 5.1 2025/02/12 22:22:20 kls Exp $
|
||||
*/
|
||||
|
||||
#define MUTE_DEPRECATED_MAINTHREADHOOK
|
||||
#include "plugin.h"
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
|
5
plugin.h
5
plugin.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: plugin.h 4.1 2020/06/29 09:29:06 kls Exp $
|
||||
* $Id: plugin.h 5.1 2025/02/12 22:22:20 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __PLUGIN_H
|
||||
@ -43,6 +43,9 @@ public:
|
||||
virtual bool Start(void);
|
||||
virtual void Stop(void);
|
||||
virtual void Housekeeping(void);
|
||||
#ifndef MUTE_DEPRECATED_MAINTHREADHOOK
|
||||
[[deprecated("use proper locking instead")]]
|
||||
#endif
|
||||
virtual void MainThreadHook(void);
|
||||
virtual cString Active(void);
|
||||
virtual time_t WakeupTime(void);
|
||||
|
8
po/ar.po
8
po/ar.po
@ -134,8 +134,8 @@ msgstr "News Magazine"
|
||||
msgid "Content$Documentary"
|
||||
msgstr "Documentary"
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgstr "Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr "Discussion/Interview/Debate"
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
msgstr "Show/Game Show"
|
||||
@ -212,8 +212,8 @@ msgstr "Rock/Pop"
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr "Serious/Classical Music"
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgstr "Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr "Folk/Traditional Music"
|
||||
|
||||
msgid "Content$Jazz"
|
||||
msgstr "Jazz"
|
||||
|
@ -133,7 +133,7 @@ msgstr "Revista de not
|
||||
msgid "Content$Documentary"
|
||||
msgstr "Documental"
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr "Discussió/Entrevista/Debat"
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
@ -211,7 +211,7 @@ msgstr "Rock/Pop"
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr "Música clàssica/seriosa"
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr "Música folklòrica/tradicional"
|
||||
|
||||
msgid "Content$Jazz"
|
||||
|
@ -133,7 +133,7 @@ msgstr "zprávy"
|
||||
msgid "Content$Documentary"
|
||||
msgstr "dokumentární"
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr "diskuze/rozhovor/debata"
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
@ -211,7 +211,7 @@ msgstr "rock/pop"
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr "vážná/klasická hudba"
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr "folk/country"
|
||||
|
||||
msgid "Content$Jazz"
|
||||
|
@ -130,7 +130,7 @@ msgstr ""
|
||||
msgid "Content$Documentary"
|
||||
msgstr ""
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr ""
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
@ -208,7 +208,7 @@ msgstr ""
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr ""
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr ""
|
||||
|
||||
msgid "Content$Jazz"
|
||||
|
@ -132,7 +132,7 @@ msgstr "Nachrichtenmagazin"
|
||||
msgid "Content$Documentary"
|
||||
msgstr "Dokumentation"
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr "Diskussion/Interview/Debatte"
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
@ -142,7 +142,7 @@ msgid "Content$Game Show/Quiz/Contest"
|
||||
msgstr "Spielshow/Quiz/Wettbewerb"
|
||||
|
||||
msgid "Content$Variety Show"
|
||||
msgstr "Variete-Show"
|
||||
msgstr "Varieté-Show"
|
||||
|
||||
msgid "Content$Talk Show"
|
||||
msgstr "Talkshow"
|
||||
@ -210,7 +210,7 @@ msgstr "Rock/Pop"
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr "Ernste/Klassische Musik"
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr "Volks/Traditionelle Musik"
|
||||
|
||||
msgid "Content$Jazz"
|
||||
|
@ -130,7 +130,7 @@ msgstr ""
|
||||
msgid "Content$Documentary"
|
||||
msgstr ""
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr ""
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
@ -208,7 +208,7 @@ msgstr ""
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr ""
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr ""
|
||||
|
||||
msgid "Content$Jazz"
|
||||
|
@ -131,7 +131,7 @@ msgstr "Revista de noticias"
|
||||
msgid "Content$Documentary"
|
||||
msgstr "Documental"
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr "Discusión/Entrevista/Debate"
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
@ -209,7 +209,7 @@ msgstr "Rock/Pop"
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr "Musica clásica"
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr "Musica Folk/Tradicional"
|
||||
|
||||
msgid "Content$Jazz"
|
||||
|
@ -130,7 +130,7 @@ msgstr "Uudisteajakiri"
|
||||
msgid "Content$Documentary"
|
||||
msgstr "Dokumentaal"
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr "Diskussioon/intervjuu/debatt"
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
@ -208,7 +208,7 @@ msgstr "Rock/pop"
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr "Klassikaline muusika"
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr "Folk/rahvamuusika"
|
||||
|
||||
msgid "Content$Jazz"
|
||||
|
16
po/fi_FI.po
16
po/fi_FI.po
@ -134,7 +134,7 @@ msgstr "Uutismakasiini"
|
||||
msgid "Content$Documentary"
|
||||
msgstr "Dokumentti"
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr "Keskustelu/haastattelu/väittely"
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
@ -212,7 +212,7 @@ msgstr "Rock/pop"
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr "Vakava/klassinen musiikki"
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr "Folk/kansanmusiikki"
|
||||
|
||||
msgid "Content$Jazz"
|
||||
@ -797,7 +797,7 @@ msgid "Folder"
|
||||
msgstr "Kansio"
|
||||
|
||||
msgid "Size"
|
||||
msgstr ""
|
||||
msgstr "Koko"
|
||||
|
||||
msgid "This folder is currently in use - no changes are possible!"
|
||||
msgstr "Kansio on käytössä - muokkaukset eivät mahdollisia!"
|
||||
@ -846,7 +846,7 @@ msgid "Edited version already exists - overwrite?"
|
||||
msgstr "Muokattava versio on jo olemassa - ylikirjoitetaanko?"
|
||||
|
||||
msgid "Not enough free disk space to start editing process!"
|
||||
msgstr ""
|
||||
msgstr "Tallennustila ei riitä muokkaamiseen!"
|
||||
|
||||
msgid "Error while queueing recording for cutting!"
|
||||
msgstr "Tallenteen lisääminen leikkausjonoon epäonnistui!"
|
||||
@ -1526,7 +1526,7 @@ msgid "Button$Insert"
|
||||
msgstr "Lisää"
|
||||
|
||||
msgid "Button$Macro"
|
||||
msgstr ""
|
||||
msgstr "Makro"
|
||||
|
||||
msgid "Plugin"
|
||||
msgstr "Laajennos"
|
||||
@ -1535,7 +1535,7 @@ msgid "Up/Dn for new location - OK to move"
|
||||
msgstr "'Ylös/Alas' uusi paikka - 'OK' hyväksy"
|
||||
|
||||
msgid "Primary device has no MPEG decoder, can't attach player!"
|
||||
msgstr ""
|
||||
msgstr "Ensisijaissa laitteessa ei ole MPEG-toistinta!"
|
||||
|
||||
msgid "Low disk space!"
|
||||
msgstr "Tallennustila loppumassa!"
|
||||
@ -1580,10 +1580,10 @@ msgstr "käynnistetäänkö uudelleen?"
|
||||
|
||||
#. TRANSLATORS: note the plural/singular!
|
||||
msgid "errors"
|
||||
msgstr ""
|
||||
msgstr "virhettä"
|
||||
|
||||
msgid "error"
|
||||
msgstr ""
|
||||
msgstr "virhe"
|
||||
|
||||
#. TRANSLATORS: note the trailing blank!
|
||||
msgid "Volume "
|
||||
|
@ -141,7 +141,7 @@ msgstr "Magazine d'information"
|
||||
msgid "Content$Documentary"
|
||||
msgstr "Documentaire"
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr "Discussion/Interview/Débat"
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
@ -219,7 +219,7 @@ msgstr "Rock/Pop"
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr "Sérieux/Musique Classique"
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr "Folk/Musique Traditionnelle"
|
||||
|
||||
msgid "Content$Jazz"
|
||||
|
@ -132,7 +132,7 @@ msgstr ""
|
||||
msgid "Content$Documentary"
|
||||
msgstr ""
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr ""
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
@ -210,7 +210,7 @@ msgstr ""
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr ""
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr ""
|
||||
|
||||
msgid "Content$Jazz"
|
||||
|
@ -138,7 +138,7 @@ msgstr "Hírmagazin"
|
||||
msgid "Content$Documentary"
|
||||
msgstr "Dokumentumfilm"
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr "Beszélgetés/Interjú/Vita"
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
@ -216,7 +216,7 @@ msgstr "Rock/Pop"
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr "Komolyzene/Klasszikus zene"
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr "Népzene/Hagyományos zene"
|
||||
|
||||
msgid "Content$Jazz"
|
||||
|
@ -12,7 +12,7 @@ msgstr ""
|
||||
"Project-Id-Version: VDR 2.6.0\n"
|
||||
"Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
|
||||
"POT-Creation-Date: 2024-09-21 12:45+0200\n"
|
||||
"PO-Revision-Date: 2024-09-14 13:05+0200\n"
|
||||
"PO-Revision-Date: 2024-10-15 00:35+0200\n"
|
||||
"Last-Translator: Gringo <openpli@tiscali.it>\n"
|
||||
"Language-Team: Italian <vdr@linuxtv.org>\n"
|
||||
"Language: it\n"
|
||||
@ -136,7 +136,7 @@ msgstr "Settimanale di attualità"
|
||||
msgid "Content$Documentary"
|
||||
msgstr "Documentario"
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr "Discussione/Intervista/Dibattito"
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
@ -214,7 +214,7 @@ msgstr "Rock/Pop"
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr "Musica Classica/Seria"
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr "Musica Tradizionale/Folclore"
|
||||
|
||||
msgid "Content$Jazz"
|
||||
@ -1585,7 +1585,7 @@ msgid "errors"
|
||||
msgstr "errori"
|
||||
|
||||
msgid "error"
|
||||
msgstr ""
|
||||
msgstr "errore"
|
||||
|
||||
#. TRANSLATORS: note the trailing blank!
|
||||
msgid "Volume "
|
||||
|
@ -130,7 +130,7 @@ msgstr "Naujienų žurnalas"
|
||||
msgid "Content$Documentary"
|
||||
msgstr "Dokumentika"
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr "Diskusijos/Interviu"
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
@ -208,7 +208,7 @@ msgstr "Rock/Pop"
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr "Klasikinė muzika"
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr "Folk/Tradizinė muzika"
|
||||
|
||||
msgid "Content$Jazz"
|
||||
|
@ -132,7 +132,7 @@ msgstr "Магазин"
|
||||
msgid "Content$Documentary"
|
||||
msgstr "Документарен"
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr "Дискусија/Интервју/Дебата"
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
@ -210,7 +210,7 @@ msgstr "Рок/Поп"
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr "Сериозна/Класична музика"
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr "Фолк/Народна музика"
|
||||
|
||||
msgid "Content$Jazz"
|
||||
|
@ -136,7 +136,7 @@ msgstr "Nieuwsbulletin"
|
||||
msgid "Content$Documentary"
|
||||
msgstr "Documentaire"
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr "Discussie/Interview/Debat"
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
@ -214,7 +214,7 @@ msgstr "Rock/Pop"
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr "Serieuze muziek/Klassieke muziek"
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr "Folk/Traditionele muziek"
|
||||
|
||||
msgid "Content$Jazz"
|
||||
|
@ -131,7 +131,7 @@ msgstr ""
|
||||
msgid "Content$Documentary"
|
||||
msgstr ""
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr ""
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
@ -209,7 +209,7 @@ msgstr ""
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr ""
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr ""
|
||||
|
||||
msgid "Content$Jazz"
|
||||
|
@ -135,7 +135,7 @@ msgstr "Magazyny informacyjne"
|
||||
msgid "Content$Documentary"
|
||||
msgstr "Dokumentalne"
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr "Dyskusje/Wywiady/Debaty"
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
@ -213,7 +213,7 @@ msgstr "Rock/Pop"
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr "Muzyka klasyczna"
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr "Folk/Muzyka tradycyjna"
|
||||
|
||||
msgid "Content$Jazz"
|
||||
|
@ -131,7 +131,7 @@ msgstr "Notici
|
||||
msgid "Content$Documentary"
|
||||
msgstr "Documentário"
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr "Discussão/Entrevista/Debate"
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
@ -209,7 +209,7 @@ msgstr "Rock/Pop"
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr "Música Clássica/Séria"
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr "Música Tradicional/Folclore"
|
||||
|
||||
msgid "Content$Jazz"
|
||||
|
@ -132,7 +132,7 @@ msgstr "Magazin de ştiri"
|
||||
msgid "Content$Documentary"
|
||||
msgstr "Documentar"
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr "Discuţie/Interviu/Dezbatere"
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
@ -210,7 +210,7 @@ msgstr "Rock/Pop"
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr "Muzică clasică/serioasă"
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr "Muzică folk/tradiţională"
|
||||
|
||||
msgid "Content$Jazz"
|
||||
|
@ -131,7 +131,7 @@ msgstr "Новостной журнал"
|
||||
msgid "Content$Documentary"
|
||||
msgstr "Документальные"
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr "Дискуссия/Интервью/Дебаты"
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
@ -209,7 +209,7 @@ msgstr "Рок/Поп"
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr "Классическая музыка"
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr "Фольклор/Традиционная музыка"
|
||||
|
||||
msgid "Content$Jazz"
|
||||
|
@ -131,7 +131,7 @@ msgstr "Spravodajsk
|
||||
msgid "Content$Documentary"
|
||||
msgstr "Dokumentárny"
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr "Diskusia/Rozhovor/debata"
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
@ -209,7 +209,7 @@ msgstr "Rock/Pop"
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr "Vá¾na/Klasická hudba"
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr "¥udová/Tradièná Hudba"
|
||||
|
||||
msgid "Content$Jazz"
|
||||
|
@ -131,7 +131,7 @@ msgstr "Poro
|
||||
msgid "Content$Documentary"
|
||||
msgstr "Dokumentarec"
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr "Diskudija/Interviju/Debata"
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
@ -209,7 +209,7 @@ msgstr "Rok/Pop"
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr "Resna/Klasièna Glasba"
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr "Narodna/Tradicionalna glasba"
|
||||
|
||||
msgid "Content$Jazz"
|
||||
|
@ -131,7 +131,7 @@ msgstr "Novosti"
|
||||
msgid "Content$Documentary"
|
||||
msgstr "Dokumentarni"
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr "Diskusija/Razgovor/Debata"
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
@ -209,7 +209,7 @@ msgstr "Rok/Pop"
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr "Ozbiljna/Klasièna muzika"
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr "Narodna/Izvorna muzika"
|
||||
|
||||
msgid "Content$Jazz"
|
||||
|
@ -135,7 +135,7 @@ msgstr "Nyhetsmagasin"
|
||||
msgid "Content$Documentary"
|
||||
msgstr "Dokumentär"
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr "Diskussion/Intervju/Debatt"
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
@ -213,7 +213,7 @@ msgstr "Rock/Pop"
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr "Klassisk musik"
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr "Folkmusik"
|
||||
|
||||
msgid "Content$Jazz"
|
||||
|
@ -130,7 +130,7 @@ msgstr ""
|
||||
msgid "Content$Documentary"
|
||||
msgstr ""
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr ""
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
@ -208,7 +208,7 @@ msgstr ""
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr ""
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr ""
|
||||
|
||||
msgid "Content$Jazz"
|
||||
|
@ -131,7 +131,7 @@ msgstr "Журнал новин"
|
||||
msgid "Content$Documentary"
|
||||
msgstr "Документальне"
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr "Дискусія/Інтерв’ю/Дебати"
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
@ -209,7 +209,7 @@ msgstr "Рок/Поп"
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr "Серйозна/Класична музика"
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr "Фльк/Традиційна музика"
|
||||
|
||||
msgid "Content$Jazz"
|
||||
|
@ -132,8 +132,8 @@ msgstr "新闻杂志"
|
||||
msgid "Content$Documentary"
|
||||
msgstr "记录片"
|
||||
|
||||
msgid "Content$Discussion/Inverview/Debate"
|
||||
msgstr "讨论/ Inverview/辩论"
|
||||
msgid "Content$Discussion/Interview/Debate"
|
||||
msgstr "讨论/ Interview/辩论"
|
||||
|
||||
msgid "Content$Show/Game Show"
|
||||
msgstr "显示/游戏展"
|
||||
@ -210,7 +210,7 @@ msgstr "摇滚/流行"
|
||||
msgid "Content$Serious/Classical Music"
|
||||
msgstr "严重/古典音乐"
|
||||
|
||||
msgid "Content$Folk/Tradional Music"
|
||||
msgid "Content$Folk/Traditional Music"
|
||||
msgstr "民谣/传统体育专业课程设置的音乐"
|
||||
|
||||
msgid "Content$Jazz"
|
||||
|
11
recording.c
11
recording.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: recording.c 5.35 2024/09/21 19:18:18 kls Exp $
|
||||
* $Id: recording.c 5.37 2025/01/18 20:57:06 kls Exp $
|
||||
*/
|
||||
|
||||
#include "recording.h"
|
||||
@ -356,6 +356,7 @@ void cResumeFile::Delete(void)
|
||||
|
||||
cRecordingInfo::cRecordingInfo(const cChannel *Channel, const cEvent *Event)
|
||||
{
|
||||
modified = 0;
|
||||
channelID = Channel ? Channel->GetChannelID() : tChannelID::InvalidID;
|
||||
channelName = Channel ? strdup(Channel->Name()) : NULL;
|
||||
ownEvent = Event ? NULL : new cEvent(0);
|
||||
@ -420,6 +421,7 @@ cRecordingInfo::cRecordingInfo(const cChannel *Channel, const cEvent *Event)
|
||||
|
||||
cRecordingInfo::cRecordingInfo(const char *FileName)
|
||||
{
|
||||
modified = 0;
|
||||
channelID = tChannelID::InvalidID;
|
||||
channelName = NULL;
|
||||
ownEvent = new cEvent(0);
|
||||
@ -488,6 +490,12 @@ void cRecordingInfo::SetErrors(int Errors)
|
||||
bool cRecordingInfo::Read(FILE *f)
|
||||
{
|
||||
if (ownEvent) {
|
||||
struct stat st;
|
||||
if (fstat(fileno(f), &st))
|
||||
return false;
|
||||
if (modified == st.st_mtime)
|
||||
return true;
|
||||
modified = st.st_mtime;
|
||||
cReadLine ReadLine;
|
||||
char *s;
|
||||
int line = 0;
|
||||
@ -1346,6 +1354,7 @@ bool cRecording::ChangeName(const char *NewName)
|
||||
fileName = strdup(OldFileName);
|
||||
return false;
|
||||
}
|
||||
info->SetFileName(NewFileName);
|
||||
isOnVideoDirectoryFileSystem = -1; // it might have been moved to a different file system
|
||||
ClearSortName();
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: recording.h 5.11 2024/09/19 20:21:58 kls Exp $
|
||||
* $Id: recording.h 5.12 2025/01/15 10:50:29 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __RECORDING_H
|
||||
@ -64,6 +64,7 @@ public:
|
||||
class cRecordingInfo {
|
||||
friend class cRecording;
|
||||
private:
|
||||
time_t modified;
|
||||
tChannelID channelID;
|
||||
char *channelName;
|
||||
const cEvent *event;
|
||||
|
13
remux.c
13
remux.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: remux.c 5.13 2024/09/21 19:18:18 kls Exp $
|
||||
* $Id: remux.c 5.18 2024/12/05 10:37:15 kls Exp $
|
||||
*/
|
||||
|
||||
#include "remux.h"
|
||||
@ -287,6 +287,8 @@ uchar cTsPayload::GetByte(void)
|
||||
if (TsPid(p) == pid) { // only handle TS packets for the initial PID
|
||||
if (++numPacketsPid > MAX_TS_PACKETS_FOR_VIDEO_FRAME_DETECTION)
|
||||
return SetEof();
|
||||
if (TsError(p))
|
||||
return SetEof(); // don't parse TS packets with errors
|
||||
if (TsHasPayload(p)) {
|
||||
if (index > 0 && TsPayloadStart(p)) // checking index to not skip the very first TS packet
|
||||
return SetEof();
|
||||
@ -2073,8 +2075,10 @@ void cFrameChecker::CheckFrame(const uchar *Data, int Length, bool IndependentFr
|
||||
Report("duplicate backref");
|
||||
backRefs |= b;
|
||||
}
|
||||
else
|
||||
else {
|
||||
Report("rev diff too big");
|
||||
lastPts = Pts;
|
||||
}
|
||||
}
|
||||
else
|
||||
Report("zero diff");
|
||||
@ -2153,7 +2157,7 @@ void cFrameDetector::SetMissing(void)
|
||||
frameChecker->SetMissing();
|
||||
}
|
||||
|
||||
bool cFrameDetector::NewFrame(int *PreviousErrors, int * MissingFrames)
|
||||
bool cFrameDetector::NewFrame(int *PreviousErrors, int *MissingFrames)
|
||||
{
|
||||
if (newFrame) {
|
||||
if (PreviousErrors)
|
||||
@ -2267,11 +2271,12 @@ int cFrameDetector::Analyze(const uchar *Data, int Length, bool ErrorCheck)
|
||||
framesPerSecond = 60.0 / 1.001;
|
||||
else {
|
||||
framesPerSecond = DEFAULTFRAMESPERSECOND;
|
||||
dsyslog("unknown frame delta (%d), assuming %5.2f fps", Delta, DEFAULTFRAMESPERSECOND);
|
||||
dsyslog("unknown frame delta (%d), assuming %5.2f fps", Delta, framesPerSecond);
|
||||
}
|
||||
}
|
||||
else // audio
|
||||
framesPerSecond = double(PTSTICKS) / Delta; // PTS of audio frames is always increasing
|
||||
frameChecker->SetFrameDelta(PTSTICKS / framesPerSecond);
|
||||
dbgframes("\nDelta = %d FPS = %5.2f FPPU = %d NF = %d TRO = %d\n", Delta, framesPerSecond, framesPerPayloadUnit, numPtsValues + 1, parser->IFrameTemporalReferenceOffset());
|
||||
synced = true;
|
||||
parser->SetDebug(false);
|
||||
|
4
remux.h
4
remux.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: remux.h 5.7 2024/09/21 19:18:18 kls Exp $
|
||||
* $Id: remux.h 5.8 2024/12/04 14:33:22 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __REMUX_H
|
||||
@ -570,7 +570,7 @@ public:
|
||||
///< is scanned for the PAT/PMT and then a rewind is done on the file.
|
||||
bool Synced(void) { return synced; }
|
||||
///< Returns true if the frame detector has synced on the data stream.
|
||||
bool NewFrame(int *PreviousErrors = NULL, int * MissingFrames = NULL);
|
||||
bool NewFrame(int *PreviousErrors = NULL, int *MissingFrames = NULL);
|
||||
///< Returns true if the data given to the last call to Analyze() started a
|
||||
///< new frame. If PreviousErrors is given, it will be set to the number of errors in
|
||||
///< the previous frame. If MissingFrames is given, it will be set to the number of
|
||||
|
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: skinlcars.c 5.7 2024/09/21 10:53:07 kls Exp $
|
||||
* $Id: skinlcars.c 5.8 2024/12/02 12:40:56 kls Exp $
|
||||
*/
|
||||
|
||||
// "Star Trek: The Next Generation"(R) is a registered trademark of Paramount Pictures,
|
||||
@ -1259,6 +1259,7 @@ void cSkinLCARSDisplayMenu::DrawTimers(void)
|
||||
int NumDevices = 0;
|
||||
int y = ys04;
|
||||
// Timers and recording devices:
|
||||
LOCK_SCHEDULES_READ;
|
||||
while (1) {
|
||||
int NumTimers = 0;
|
||||
const cDevice *Device = NULL;
|
||||
|
6
skins.c
6
skins.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: skins.c 5.4 2024/09/21 16:21:08 kls Exp $
|
||||
* $Id: skins.c 5.5 2025/02/12 21:18:53 kls Exp $
|
||||
*/
|
||||
|
||||
#include "skins.h"
|
||||
@ -305,7 +305,7 @@ eKeys cSkins::Message(eMessageType Type, const char *s, int Seconds)
|
||||
}
|
||||
cSkinDisplay::Current()->SetMessage(Type, s);
|
||||
cSkinDisplay::Current()->Flush();
|
||||
cStatus::MsgOsdStatusMessage(s);
|
||||
cStatus::MsgOsdStatusMessage(Type, s);
|
||||
eKeys k = kNone;
|
||||
if (Type != mtStatus) {
|
||||
k = Interface->Wait(Seconds);
|
||||
@ -316,7 +316,7 @@ eKeys cSkins::Message(eMessageType Type, const char *s, int Seconds)
|
||||
}
|
||||
else {
|
||||
cSkinDisplay::Current()->SetMessage(Type, NULL);
|
||||
cStatus::MsgOsdStatusMessage(NULL);
|
||||
cStatus::MsgOsdStatusMessage(Type, NULL);
|
||||
}
|
||||
}
|
||||
else if (!s && displayMessage) {
|
||||
|
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: sources.c 3.6 2014/03/09 12:05:42 kls Exp $
|
||||
* $Id: sources.c 5.1 2024/10/09 10:36:16 kls Exp $
|
||||
*/
|
||||
|
||||
#include "sources.h"
|
||||
@ -46,10 +46,7 @@ bool cSource::Matches(int Code1, int Code2)
|
||||
|
||||
int cSource::Position(int Code)
|
||||
{
|
||||
int n = (Code & st_Pos);
|
||||
if (n > 0x00007FFF)
|
||||
n |= 0xFFFF0000;
|
||||
return n;
|
||||
return int16_t(Code & st_Pos);
|
||||
}
|
||||
|
||||
cString cSource::ToString(int Code)
|
||||
|
14
status.c
14
status.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: status.c 4.1 2018/01/29 13:36:53 kls Exp $
|
||||
* $Id: status.c 5.3 2025/02/12 21:18:53 kls Exp $
|
||||
*/
|
||||
|
||||
#include "status.h"
|
||||
@ -95,10 +95,10 @@ void cStatus::MsgOsdTitle(const char *Title)
|
||||
sm->OsdTitle(Title);
|
||||
}
|
||||
|
||||
void cStatus::MsgOsdStatusMessage(const char *Message)
|
||||
void cStatus::MsgOsdStatusMessage(eMessageType Type, const char *Message)
|
||||
{
|
||||
for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
|
||||
sm->OsdStatusMessage(Message);
|
||||
sm->OsdStatusMessage2(Type, Message);
|
||||
}
|
||||
|
||||
void cStatus::MsgOsdHelpKeys(const char *Red, const char *Green, const char *Yellow, const char *Blue)
|
||||
@ -107,16 +107,16 @@ void cStatus::MsgOsdHelpKeys(const char *Red, const char *Green, const char *Yel
|
||||
sm->OsdHelpKeys(Red, Green, Yellow, Blue);
|
||||
}
|
||||
|
||||
void cStatus::MsgOsdItem(const char *Text, int Index)
|
||||
void cStatus::MsgOsdItem(const char *Text, int Index, bool Selectable)
|
||||
{
|
||||
for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
|
||||
sm->OsdItem(Text, Index);
|
||||
sm->OsdItem2(Text, Index, Selectable);
|
||||
}
|
||||
|
||||
void cStatus::MsgOsdCurrentItem(const char *Text)
|
||||
void cStatus::MsgOsdCurrentItem(const char *Text, int Index)
|
||||
{
|
||||
for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
|
||||
sm->OsdCurrentItem(Text);
|
||||
sm->OsdCurrentItem2(Text, Index);
|
||||
}
|
||||
|
||||
void cStatus::MsgOsdTextItem(const char *Text, bool Scroll)
|
||||
|
18
status.h
18
status.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: status.h 4.4 2018/01/29 13:42:17 kls Exp $
|
||||
* $Id: status.h 5.3 2025/02/12 21:18:53 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __STATUS_H
|
||||
@ -13,6 +13,7 @@
|
||||
#include "config.h"
|
||||
#include "device.h"
|
||||
#include "player.h"
|
||||
#include "skins.h"
|
||||
#include "tools.h"
|
||||
|
||||
// Several member functions of the following classes are called with a pointer to
|
||||
@ -81,14 +82,21 @@ protected:
|
||||
virtual void OsdTitle(const char *Title) {}
|
||||
// Title has been displayed in the title line of the menu.
|
||||
virtual void OsdStatusMessage(const char *Message) {}
|
||||
virtual void OsdStatusMessage2(eMessageType Type, const char *Message) { OsdStatusMessage(Message); }
|
||||
// Message has been displayed in the status line of the menu.
|
||||
// If Message is NULL, the status line has been cleared.
|
||||
virtual void OsdHelpKeys(const char *Red, const char *Green, const char *Yellow, const char *Blue) {}
|
||||
// The help keys have been set to the given values (may be NULL).
|
||||
virtual void OsdItem(const char *Text, int Index) {}
|
||||
// The OSD displays the given single line Text as menu item at Index.
|
||||
virtual void OsdItem2(const char *Text, int Index, bool Selectable) { OsdItem(Text, Index); }
|
||||
// The OSD displays the given single line Text as menu item at Index.
|
||||
// Selectable is true if this item can be selected.
|
||||
virtual void OsdCurrentItem(const char *Text) {}
|
||||
// The OSD displays the given single line Text as the current menu item.
|
||||
virtual void OsdCurrentItem2(const char *Text, int Index) { OsdCurrentItem(Text); }
|
||||
// The OSD displays the given single line Text as the current menu item.
|
||||
// Index is the one that was given in OsdItem[2]() for this item.
|
||||
virtual void OsdTextItem(const char *Text, bool Scroll) {}
|
||||
// The OSD displays the given multi line text. If Text points to an
|
||||
// actual string, that text shall be displayed and Scroll has no
|
||||
@ -115,10 +123,12 @@ public:
|
||||
static void MsgSetSubtitleTrack(int Index, const char * const *Tracks);
|
||||
static void MsgOsdClear(void);
|
||||
static void MsgOsdTitle(const char *Title);
|
||||
static void MsgOsdStatusMessage(const char *Message);
|
||||
[[deprecated("use MsgOsdStatusMessage(eMessageType Type, const char *Message) instead")]]
|
||||
static void MsgOsdStatusMessage(const char *Message) { MsgOsdStatusMessage(mtStatus, Message); }
|
||||
static void MsgOsdStatusMessage(eMessageType Type, const char *Message);
|
||||
static void MsgOsdHelpKeys(const char *Red, const char *Green, const char *Yellow, const char *Blue);
|
||||
static void MsgOsdItem(const char *Text, int Index);
|
||||
static void MsgOsdCurrentItem(const char *Text);
|
||||
static void MsgOsdItem(const char *Text, int Index, bool Selectable = true);
|
||||
static void MsgOsdCurrentItem(const char *Text, int Index = -1);
|
||||
static void MsgOsdTextItem(const char *Text, bool Scroll = false);
|
||||
static void MsgOsdChannel(const char *Text);
|
||||
static void MsgOsdProgramme(time_t PresentTime, const char *PresentTitle, const char *PresentSubtitle, time_t FollowingTime, const char *FollowingTitle, const char *FollowingSubtitle);
|
||||
|
3
thread.c
3
thread.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: thread.c 5.2 2024/01/18 13:01:07 kls Exp $
|
||||
* $Id: thread.c 5.3 2025/01/15 08:43:12 kls Exp $
|
||||
*/
|
||||
|
||||
#include "thread.h"
|
||||
@ -597,6 +597,7 @@ cStateLockLog::cStateLockLog(void)
|
||||
void cStateLockLog::Dump(const char *Name, tThreadId ThreadId)
|
||||
{
|
||||
dsyslog("--- begin invalid lock sequence report");
|
||||
dsyslog("TID T C R DR S ST");
|
||||
int LastFlags = 0;
|
||||
for (int i = 0; i < SLL_SIZE; i++) {
|
||||
if (tThreadId tid = logThreadIds[logIndex]) {
|
||||
|
56
timers.c
56
timers.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: timers.c 5.20 2024/03/06 14:37:15 kls Exp $
|
||||
* $Id: timers.c 5.25 2025/01/13 14:44:18 kls Exp $
|
||||
*/
|
||||
|
||||
#include "timers.h"
|
||||
@ -185,6 +185,8 @@ cTimer::cTimer(const cEvent *Event, const char *FileName, const cTimer *PatternT
|
||||
deferred = 0;
|
||||
pending = inVpsMargin = false;
|
||||
flags = tfActive;
|
||||
if (PatternTimer)
|
||||
SetFlags(tfSpawned);
|
||||
*pattern = 0;
|
||||
*file = 0;
|
||||
aux = NULL;
|
||||
@ -284,10 +286,12 @@ void cTimer::CalcMargins(int &MarginStart, int &MarginStop, const cEvent *Event)
|
||||
MarginStop = Setup.MarginStop * 60;
|
||||
// To make sure the timer gets assigned to the correct event, we must
|
||||
// make sure that this is the only event that overlaps 100%:
|
||||
if (const cEvent *e = dynamic_cast<const cEvent *>(Event->Prev()))
|
||||
MarginStart = max(0, min(MarginStart, e->Duration() - 60));
|
||||
if (const cEvent *e = dynamic_cast<const cEvent *>(Event->Next()))
|
||||
MarginStop = max(0, min(MarginStop, e->Duration() - 60));
|
||||
if (HasFlags(tfSpawned)) {
|
||||
if (const cEvent *e = dynamic_cast<const cEvent *>(Event->Prev()))
|
||||
MarginStart = max(0, min(MarginStart, e->Duration() - 60));
|
||||
if (const cEvent *e = dynamic_cast<const cEvent *>(Event->Next()))
|
||||
MarginStop = max(0, min(MarginStop, e->Duration() - 60));
|
||||
}
|
||||
}
|
||||
|
||||
int cTimer::Compare(const cListObject &ListObject) const
|
||||
@ -612,7 +616,7 @@ bool cTimer::Matches(time_t t, bool Directly, int Margin) const
|
||||
return false;
|
||||
deferred = 0;
|
||||
|
||||
if (HasFlags(tfActive)) {
|
||||
if (HasFlags(tfActive) && !Remote()) {
|
||||
if (event) {
|
||||
if (HasFlags(tfVps)) {
|
||||
if (event->Vps()) {
|
||||
@ -620,7 +624,8 @@ bool cTimer::Matches(time_t t, bool Directly, int Margin) const
|
||||
startTime = event->StartTime();
|
||||
stopTime = event->EndTime();
|
||||
if (!Margin) { // this is an actual check
|
||||
if (event->Schedule()->PresentSeenWithin(EITPRESENTFOLLOWINGRATE)) { // VPS control can only work with up-to-date events...
|
||||
const cSchedule *Schedule = event->Schedule();
|
||||
if (Schedule && Schedule->PresentSeenWithin(EITPRESENTFOLLOWINGRATE)) { // VPS control can only work with up-to-date events...
|
||||
if (!vpsActive) {
|
||||
vpsActive = true;
|
||||
if (Recording())
|
||||
@ -636,7 +641,7 @@ bool cTimer::Matches(time_t t, bool Directly, int Margin) const
|
||||
return running || time(NULL) < vpsNotRunning + VPSGRACE;
|
||||
}
|
||||
if (Recording()) {
|
||||
if (event->Schedule()->PresentSeenWithin(EITPRESENTFOLLOWINGGRACE))
|
||||
if (Schedule && Schedule->PresentSeenWithin(EITPRESENTFOLLOWINGGRACE))
|
||||
return event->IsRunning(true); // give it a chance to recover - worst case: the recording will be 60 seconds too long
|
||||
if (vpsActive) {
|
||||
vpsActive = false;
|
||||
@ -726,10 +731,39 @@ eTimerMatch cTimer::Matches(const cEvent *Event, int *Overlap) const
|
||||
bool cTimer::Expired(void) const
|
||||
{
|
||||
if (IsSingleEvent() && !Recording()) {
|
||||
time_t Now = time(NULL);
|
||||
time_t ExpireTime = StopTimeEvent();
|
||||
if (HasFlags(tfVps))
|
||||
if (HasFlags(tfVps)) {
|
||||
ExpireTime += EXPIRELATENCY;
|
||||
return ExpireTime <= time(NULL);
|
||||
if (ExpireTime <= Now) {
|
||||
LOCK_SCHEDULES_READ;
|
||||
const cSchedule *Schedule = event ? event->Schedule() : NULL;
|
||||
const cEvent *FirstEvent = event;
|
||||
if (Schedule)
|
||||
FirstEvent = Schedule->Events()->Next(FirstEvent);
|
||||
else if ((Schedule = Schedules->GetSchedule(Channel())) != NULL) {
|
||||
FirstEvent = Schedule->Events()->First();
|
||||
if (FirstEvent)
|
||||
dsyslog("timer %s had no event, got %s from channel/schedule", *ToDescr(), *FirstEvent->ToDescr());
|
||||
}
|
||||
if (FirstEvent) {
|
||||
if (Schedule) {
|
||||
for (const cEvent *e = FirstEvent; e; e = Schedule->Events()->Next(e)) {
|
||||
if (e->Vps() == startTime) {
|
||||
ExpireTime = e->EndTime() + EXPIRELATENCY;
|
||||
dsyslog("timer %s is waiting for next VPS event %s", *ToDescr(), *e->ToDescr());
|
||||
// no break here - let's play it safe and look at *all* events
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
dsyslog("timer %s has no event, setting expiration to +24h", *ToDescr());
|
||||
ExpireTime += 3600 * 24;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ExpireTime <= Now;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -783,7 +817,6 @@ cTimer *cTimer::SpawnPatternTimer(const cEvent *Event, cTimers *Timers)
|
||||
cString FileName = MakePatternFileName(Pattern(), Event->Title(), Event->ShortText(), File());
|
||||
isyslog("spawning timer %s for event %s", *ToDescr(), *Event->ToDescr());
|
||||
cTimer *t = new cTimer(Event, FileName, this);
|
||||
t->SetFlags(tfSpawned);
|
||||
if (startswith(Pattern(), TIMERPATTERN_AVOID))
|
||||
t->SetFlags(tfAvoid);
|
||||
Timers->Add(t);
|
||||
@ -1128,6 +1161,7 @@ const cTimer *cTimers::GetMatch(time_t t) const
|
||||
{
|
||||
static int LastPending = -1;
|
||||
const cTimer *t0 = NULL;
|
||||
LOCK_SCHEDULES_READ;
|
||||
for (const cTimer *ti = First(); ti; ti = Next(ti)) {
|
||||
if (!ti->Remote() && !ti->Recording() && ti->Matches(t)) {
|
||||
if (ti->Pending()) {
|
||||
|
33
tools.c
33
tools.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: tools.c 5.14 2024/09/01 20:43:40 kls Exp $
|
||||
* $Id: tools.c 5.15 2025/01/15 08:57:45 kls Exp $
|
||||
*/
|
||||
|
||||
#include "tools.h"
|
||||
@ -131,8 +131,11 @@ char *strcpyrealloc(char *dest, const char *src)
|
||||
char *strn0cpy(char *dest, const char *src, size_t n)
|
||||
{
|
||||
char *s = dest;
|
||||
for ( ; --n && (*dest = *src) != 0; dest++, src++) ;
|
||||
*dest = 0;
|
||||
if (dest && n) {
|
||||
if (src)
|
||||
for ( ; --n && (*dest = *src) != 0; dest++, src++) ;
|
||||
*dest = 0;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -914,17 +917,21 @@ char *Utf8Strn0Cpy(char *Dest, const char *Src, int n)
|
||||
if (cCharSetConv::SystemCharacterTable())
|
||||
return strn0cpy(Dest, Src, n);
|
||||
char *d = Dest;
|
||||
while (*Src) {
|
||||
int sl = Utf8CharLen(Src);
|
||||
n -= sl;
|
||||
if (n > 0) {
|
||||
while (sl--)
|
||||
*d++ = *Src++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
if (Dest && n > 0) {
|
||||
if (Src) {
|
||||
while (*Src) {
|
||||
int sl = Utf8CharLen(Src);
|
||||
n -= sl;
|
||||
if (n > 0) {
|
||||
while (sl--)
|
||||
*d++ = *Src++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
*d = 0;
|
||||
*d = 0;
|
||||
}
|
||||
return Dest;
|
||||
}
|
||||
|
||||
|
4
tools.h
4
tools.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: tools.h 5.10 2024/09/01 20:43:40 kls Exp $
|
||||
* $Id: tools.h 5.11 2025/01/13 13:18:42 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TOOLS_H
|
||||
@ -140,7 +140,7 @@ int Utf8FromArray(const uint *a, char *s, int Size, int Max = -1);
|
||||
// When allocating buffer space, make sure we reserve enough space to hold
|
||||
// a string in UTF-8 representation:
|
||||
|
||||
#define Utf8BufSize(s) ((s) * 4)
|
||||
#define Utf8BufSize(s) ((s) * 4 + 1)
|
||||
|
||||
// The following macros automatically use the correct versions of the character
|
||||
// class functions:
|
||||
|
5
vdr.c
5
vdr.c
@ -20,9 +20,9 @@
|
||||
*
|
||||
* The author can be reached at vdr@tvdr.de
|
||||
*
|
||||
* The project's page is at http://www.tvdr.de
|
||||
* The project's page is at https://www.tvdr.de
|
||||
*
|
||||
* $Id: vdr.c 5.16 2024/03/29 21:46:50 kls Exp $
|
||||
* $Id: vdr.c 5.18 2024/12/02 12:40:56 kls Exp $
|
||||
*/
|
||||
|
||||
#include <getopt.h>
|
||||
@ -1140,6 +1140,7 @@ int main(int argc, char *argv[])
|
||||
if (Timer->Matches(Now, true, Setup.VpsMargin))
|
||||
InVpsMargin = true;
|
||||
else if (Timer->Event()) {
|
||||
LOCK_SCHEDULES_READ;
|
||||
InVpsMargin = Timer->Event()->StartTime() <= Now && Now < Timer->Event()->EndTime();
|
||||
NeedsTransponder = Timer->Event()->StartTime() - Now < VPSLOOKAHEADTIME * 3600 && !Timer->Event()->SeenWithin(VPSUPTODATETIME);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user