mirror of
https://github.com/vdr-projects/vdr.git
synced 2025-03-01 10:50:46 +00:00
Original announce message: VDR developer version 1.7.24 is now available at ftp://ftp.tvdr.de/vdr/Developer/vdr-1.7.24.tar.bz2 A 'diff' against the previous version is available at ftp://ftp.tvdr.de/vdr/Developer/vdr-1.7.23-1.7.24.diff MD5 checksums: a034c5e399417dfc583483f650d003ee vdr-1.7.24.tar.bz2 aa1a2b202da92e65945ff39470b26618 vdr-1.7.23-1.7.24.diff WARNING: ======== This is a developer version. Even though I use it in my productive environment. I strongly recommend that you only use it under controlled conditions and for testing and debugging. From the HISTORY file: - Updated the Italian OSD texts (thanks to Diego Pierotto). - Fixed a high load in case a transponder can't be received. - Improved the way DVB_API_VERSION is checked. - Updated the Finnish OSD texts (thanks to Rolf Ahrenberg). - Fixed asserting there is a live programme if the primary device is bonded with a device that starts a recording on a different band. - Fixed the return type of cMyDeviceHook::DeviceProvidesTransponder() in PLUGINS.html. - Fixed a crash in a plugin using cDeviceHook when VDR ends (reported by Oliver Endriss). - Some improvements to the Makefiles (thanks to Christian Ruppert). - Fixed cRecording::LengthInSeconds(), which wrongfully rounded the result to full minutes (thanks to Christoph Haubrich). - Symbolic links are no longer resolved in cRecordings::ScanVideoDir() (thanks to Sundararaj Reel). - The epg.data file is now read in a separate thread to make the startup process faster in case the file is very large (suggested by Helmut Auer). - Fixed selecting the primary device for receiving the live viewing channel in case it is bonded with an other device and has no receiver attached to it. - Fixed a possible crash when canceling VDR while displaying subtitles, and the primary device is no longer available. - Improved handling subtitles of BBC channels. - No longer using tabs as delimiter in the EPG bugfix log (they were garbled in the log file). - Added a missing '.' after the month in VPS strings. - Added some missing 'const' to cDevice (thanks to Joachim Wilke). - Fixed handling the PrimaryLimit when requesting a device for live viewing (reported by Uwe Scheffler). - Removed superfluous calls to SetVideoFormat() from device constructors. This function is called in cDevice::SetPrimaryDevice(), anyway. - An ongoing editing process is now canceled if either the original or the edited version of the recording is deleted from the Recordings menu. - The SVDRP command DELR now won't delete a recording that is currently being edited. - Removed code stub for obsolete SVDRP command MOVT. - The DVB device adapters/frontends are now probed by scanning the /dev/dvb directory instead of looping through adapter/frontend numbers. This allows for "holes" in the device numbering. - cReadDir::Next() now skips directory entries "." and "..". - Fixed a possible deadlock in time shift mode. - Fixed switching into time shift mode when pausing live video (thanks to Reinhard Nissl for helping to debug this one).
353 lines
9.4 KiB
Perl
Executable File
353 lines
9.4 KiB
Perl
Executable File
#!/usr/bin/perl -w
|
|
|
|
# newplugin: Initializing a new plugin source directory
|
|
#
|
|
# Creates a new plugin source directory from which to start implementing
|
|
# a plugin for VDR.
|
|
# See the file PLUGINS.html for detailed instructions on how to
|
|
# write a plugin.
|
|
#
|
|
# Usage: newplugin <name>
|
|
#
|
|
# See the main source file 'vdr.c' for copyright information and
|
|
# how to reach the author.
|
|
#
|
|
# $Id: newplugin 2.7 2012/01/18 12:32:31 kls Exp $
|
|
|
|
$PLUGIN_NAME = $ARGV[0] || die "Usage: newplugin <name>\n";
|
|
|
|
die "Please use only lowercase letters and digits in the plugin name\n" if ($PLUGIN_NAME =~ tr/a-z0-9//c);
|
|
|
|
$PLUGIN_CLASS = ucfirst($PLUGIN_NAME);
|
|
|
|
$PLUGIN_VERSION = "0.0.1";
|
|
$PLUGIN_DESCRIPTION = "Enter description for '$PLUGIN_NAME' plugin";
|
|
$PLUGIN_MAINENTRY = $PLUGIN_CLASS;
|
|
|
|
$PLUGINS_SRC = "PLUGINS/src";
|
|
|
|
$README = qq
|
|
{This is a "plugin" for the Video Disk Recorder (VDR).
|
|
|
|
Written by: Your Name <email\@host.dom>
|
|
|
|
Project's homepage: URL
|
|
|
|
Latest version available at: URL
|
|
|
|
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
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
See the file COPYING for more information.
|
|
|
|
Description:
|
|
};
|
|
|
|
$HISTORY_TITLE = "VDR Plugin '$PLUGIN_NAME' Revision History";
|
|
$HISTORY_LINE = '-' x length($HISTORY_TITLE);
|
|
$HISTORY_DATE = sprintf("%4d-%02d-%02d", (localtime)[5] + 1900, (localtime)[4] + 1, (localtime)[3]);
|
|
$HISTORY = qq
|
|
{$HISTORY_TITLE
|
|
$HISTORY_LINE
|
|
|
|
$HISTORY_DATE: Version $PLUGIN_VERSION
|
|
|
|
- Initial revision.
|
|
};
|
|
|
|
$MAKEFILE = qq
|
|
{#
|
|
# Makefile for a Video Disk Recorder plugin
|
|
#
|
|
# \$Id\$
|
|
|
|
# The official name of this plugin.
|
|
# This name will be used in the '-P...' option of VDR to load the plugin.
|
|
# By default the main source file also carries this name.
|
|
# IMPORTANT: the presence of this macro is important for the Make.config
|
|
# file. So it must be defined, even if it is not used here!
|
|
#
|
|
PLUGIN = $PLUGIN_NAME
|
|
|
|
### The version number of this plugin (taken from the main source file):
|
|
|
|
VERSION = \$(shell grep 'static const char \\*VERSION *=' \$(PLUGIN).c | awk '{ print \$\$6 }' | sed -e 's/[";]//g')
|
|
|
|
### The C++ compiler and options:
|
|
|
|
CXX ?= g++
|
|
CXXFLAGS ?= -g -O3 -Wall -Woverloaded-virtual -Wno-parentheses
|
|
|
|
### The directory environment:
|
|
|
|
VDRDIR ?= ../../..
|
|
LIBDIR ?= ../../lib
|
|
TMPDIR ?= /tmp
|
|
|
|
### Make sure that necessary options are included:
|
|
|
|
include \$(VDRDIR)/Make.global
|
|
|
|
### Allow user defined options to overwrite defaults:
|
|
|
|
-include \$(VDRDIR)/Make.config
|
|
|
|
### The version number of VDR's plugin API (taken from VDR's "config.h"):
|
|
|
|
APIVERSION = \$(shell sed -ne '/define APIVERSION/s/^.*"\\(.*\\)".*\$\$/\\1/p' \$(VDRDIR)/config.h)
|
|
|
|
### The name of the distribution archive:
|
|
|
|
ARCHIVE = \$(PLUGIN)-\$(VERSION)
|
|
PACKAGE = vdr-\$(ARCHIVE)
|
|
|
|
### Includes and Defines (add further entries here):
|
|
|
|
INCLUDES += -I\$(VDRDIR)/include
|
|
|
|
DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"\$(PLUGIN)"'
|
|
|
|
### The object files (add further files here):
|
|
|
|
OBJS = \$(PLUGIN).o
|
|
|
|
### The main target:
|
|
|
|
all: libvdr-\$(PLUGIN).so i18n
|
|
|
|
### Implicit rules:
|
|
|
|
%.o: %.c
|
|
\$(CXX) \$(CXXFLAGS) -c \$(DEFINES) \$(INCLUDES) \$<
|
|
|
|
### Dependencies:
|
|
|
|
MAKEDEP = \$(CXX) -MM -MG
|
|
DEPFILE = .dependencies
|
|
\$(DEPFILE): Makefile
|
|
\@\$(MAKEDEP) \$(DEFINES) \$(INCLUDES) \$(OBJS:%.o=%.c) > \$\@
|
|
|
|
-include \$(DEPFILE)
|
|
|
|
### Internationalization (I18N):
|
|
|
|
PODIR = po
|
|
LOCALEDIR = \$(VDRDIR)/locale
|
|
I18Npo = \$(wildcard \$(PODIR)/*.po)
|
|
I18Nmsgs = \$(addprefix \$(LOCALEDIR)/, \$(addsuffix /LC_MESSAGES/vdr-\$(PLUGIN).mo, \$(notdir \$(foreach file, \$(I18Npo), \$(basename \$(file))))))
|
|
I18Npot = \$(PODIR)/\$(PLUGIN).pot
|
|
|
|
%.mo: %.po
|
|
msgfmt -c -o \$\@ \$<
|
|
|
|
\$(I18Npot): \$(wildcard *.c)
|
|
xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-\$(PLUGIN) --package-version=\$(VERSION) --msgid-bugs-address='<see README>' -o \$\@ \$^
|
|
|
|
%.po: \$(I18Npot)
|
|
msgmerge -U --no-wrap --no-location --backup=none -q \$\@ \$<
|
|
\@touch \$\@
|
|
|
|
\$(I18Nmsgs): \$(LOCALEDIR)/%/LC_MESSAGES/vdr-\$(PLUGIN).mo: \$(PODIR)/%.mo
|
|
\@mkdir -p \$(dir \$@)
|
|
cp \$< \$\@
|
|
|
|
.PHONY: i18n
|
|
i18n: \$(I18Nmsgs) \$(I18Npot)
|
|
|
|
### Targets:
|
|
|
|
libvdr-\$(PLUGIN).so: \$(OBJS)
|
|
\$(CXX) \$(CXXFLAGS) \$(LDFLAGS) -shared \$(OBJS) -o \$\@
|
|
\@cp --remove-destination \$\@ \$(LIBDIR)/\$\@.\$(APIVERSION)
|
|
|
|
dist: \$(I18Npo) clean
|
|
\@-rm -rf \$(TMPDIR)/\$(ARCHIVE)
|
|
\@mkdir \$(TMPDIR)/\$(ARCHIVE)
|
|
\@cp -a * \$(TMPDIR)/\$(ARCHIVE)
|
|
\@tar czf \$(PACKAGE).tgz -C \$(TMPDIR) \$(ARCHIVE)
|
|
\@-rm -rf \$(TMPDIR)/\$(ARCHIVE)
|
|
\@echo Distribution package created as \$(PACKAGE).tgz
|
|
|
|
clean:
|
|
\@-rm -f \$(OBJS) \$(DEPFILE) *.so *.tgz core* *~ \$(PODIR)/*.mo \$(PODIR)/*.pot
|
|
};
|
|
|
|
$MAIN = qq
|
|
{/*
|
|
* $PLUGIN_NAME.c: A plugin for the Video Disk Recorder
|
|
*
|
|
* See the README file for copyright information and how to reach the author.
|
|
*
|
|
* \$Id\$
|
|
*/
|
|
|
|
#include <vdr/plugin.h>
|
|
|
|
static const char *VERSION = "$PLUGIN_VERSION";
|
|
static const char *DESCRIPTION = "$PLUGIN_DESCRIPTION";
|
|
static const char *MAINMENUENTRY = "$PLUGIN_MAINENTRY";
|
|
|
|
class cPlugin$PLUGIN_CLASS : public cPlugin {
|
|
private:
|
|
// Add any member variables or functions you may need here.
|
|
public:
|
|
cPlugin$PLUGIN_CLASS(void);
|
|
virtual ~cPlugin$PLUGIN_CLASS();
|
|
virtual const char *Version(void) { return VERSION; }
|
|
virtual const char *Description(void) { return DESCRIPTION; }
|
|
virtual const char *CommandLineHelp(void);
|
|
virtual bool ProcessArgs(int argc, char *argv[]);
|
|
virtual bool Initialize(void);
|
|
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; }
|
|
virtual cOsdObject *MainMenuAction(void);
|
|
virtual cMenuSetupPage *SetupMenu(void);
|
|
virtual bool SetupParse(const char *Name, const char *Value);
|
|
virtual bool Service(const char *Id, void *Data = NULL);
|
|
virtual const char **SVDRPHelpPages(void);
|
|
virtual cString SVDRPCommand(const char *Command, const char *Option, int &ReplyCode);
|
|
};
|
|
|
|
cPlugin${PLUGIN_CLASS}::cPlugin$PLUGIN_CLASS(void)
|
|
{
|
|
// Initialize any member variables here.
|
|
// DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL
|
|
// VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
|
|
}
|
|
|
|
cPlugin${PLUGIN_CLASS}::~cPlugin$PLUGIN_CLASS()
|
|
{
|
|
// Clean up after yourself!
|
|
}
|
|
|
|
const char *cPlugin${PLUGIN_CLASS}::CommandLineHelp(void)
|
|
{
|
|
// Return a string that describes all known command line options.
|
|
return NULL;
|
|
}
|
|
|
|
bool cPlugin${PLUGIN_CLASS}::ProcessArgs(int argc, char *argv[])
|
|
{
|
|
// Implement command line argument processing here if applicable.
|
|
return true;
|
|
}
|
|
|
|
bool cPlugin${PLUGIN_CLASS}::Initialize(void)
|
|
{
|
|
// Initialize any background activities the plugin shall perform.
|
|
return true;
|
|
}
|
|
|
|
bool cPlugin${PLUGIN_CLASS}::Start(void)
|
|
{
|
|
// Start any background activities the plugin shall perform.
|
|
return true;
|
|
}
|
|
|
|
void cPlugin${PLUGIN_CLASS}::Stop(void)
|
|
{
|
|
// Stop any background activities the plugin is performing.
|
|
}
|
|
|
|
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
|
|
return NULL;
|
|
}
|
|
|
|
time_t cPlugin${PLUGIN_CLASS}::WakeupTime(void)
|
|
{
|
|
// Return custom wakeup time for shutdown script
|
|
return 0;
|
|
}
|
|
|
|
cOsdObject *cPlugin${PLUGIN_CLASS}::MainMenuAction(void)
|
|
{
|
|
// Perform the action when selected from the main VDR menu.
|
|
return NULL;
|
|
}
|
|
|
|
cMenuSetupPage *cPlugin${PLUGIN_CLASS}::SetupMenu(void)
|
|
{
|
|
// Return a setup menu in case the plugin supports one.
|
|
return NULL;
|
|
}
|
|
|
|
bool cPlugin${PLUGIN_CLASS}::SetupParse(const char *Name, const char *Value)
|
|
{
|
|
// Parse your own setup parameters and store their values.
|
|
return false;
|
|
}
|
|
|
|
bool cPlugin${PLUGIN_CLASS}::Service(const char *Id, void *Data)
|
|
{
|
|
// Handle custom service requests from other plugins
|
|
return false;
|
|
}
|
|
|
|
const char **cPlugin${PLUGIN_CLASS}::SVDRPHelpPages(void)
|
|
{
|
|
// Return help text for SVDRP commands this plugin implements
|
|
return NULL;
|
|
}
|
|
|
|
cString cPlugin${PLUGIN_CLASS}::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode)
|
|
{
|
|
// Process SVDRP commands this plugin implements
|
|
return NULL;
|
|
}
|
|
|
|
VDRPLUGINCREATOR(cPlugin$PLUGIN_CLASS); // Don't touch this!
|
|
};
|
|
|
|
$PLUGINDIR = "$PLUGINS_SRC/$PLUGIN_NAME";
|
|
|
|
die "The directory $PLUGINS_SRC doesn't exist!\n" unless (-d "$PLUGINS_SRC");
|
|
die "A plugin named '$PLUGIN_NAME' already exists in $PLUGINS_SRC!\n" if (-e "$PLUGINDIR");
|
|
mkdir("$PLUGINDIR") || die "$!";
|
|
|
|
CreateFile("README", $README);
|
|
CreateFile("HISTORY", $HISTORY);
|
|
CreateFile("Makefile", $MAKEFILE);
|
|
CreateFile("$PLUGIN_NAME.c", $MAIN);
|
|
`cp COPYING "$PLUGINDIR"` if (-e "COPYING");
|
|
|
|
print qq{
|
|
The new plugin source directory has been created in "$PLUGINDIR".
|
|
|
|
The next steps you should perform now are:
|
|
|
|
* edit the file "README" to adjust it to your specific implementation
|
|
* fill in the code skeleton in "$PLUGIN_NAME.c" to implement your plugin function
|
|
* add further source files if necessary
|
|
* adapt the "Makefile" if necessary
|
|
* do "make plugins" from the VDR source directory to build your plugin
|
|
|
|
};
|
|
|
|
sub CreateFile
|
|
{
|
|
my ($Name, $Content) = @_;
|
|
open(FILE, ">$PLUGINDIR/$Name") || die "$Name: $!\n";
|
|
print FILE $Content;
|
|
close(FILE);
|
|
}
|
|
|