vdr/newplugin
Klaus Schmidinger 889f7deeb4 Version 1.7.36
VDR developer version 1.7.36 is now available at

       ftp://ftp.tvdr.de/vdr/Developer/vdr-1.7.36.tar.bz2

A 'diff' against the previous version is available at

       ftp://ftp.tvdr.de/vdr/Developer/vdr-1.7.35-1.7.36.diff

MD5 checksums:

e514f72a2a8c44f39e47b540d6ad325f  vdr-1.7.36.tar.bz2
9312a0d10bcda87d3c3c7e6dfbebcd05  vdr-1.7.35-1.7.36.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:
- Added maximum SNR value for PCTV Systems nanoStick T2 290e (thanks to Antti
  Hartikainen).
- Added a remark indicating that the coordinates of Rect in a call to
  cDevice::CanScaleVideo() are in the range of the width and height returned by
  GetOsdSize() (suggested by Reinhard Nissl).
- Modified the Makefiles (thanks to Christopher Reimer).
  By default VDR is now built according to the FHS ("File system Hierarchy Standard"),
  and a plain "make" in the VDR source directory just builds everything, but doesn't
  copy it to ./PLUGINS/lib and ./locale any more. You can use a Make.config file
  (copied from Make.config.template) and set the parameter LCLBLD=1 to have everything
  built and installed under the VDR source tree (as was the default in previous
  versions). If you already have your own Make.config file, you may want to copy the
  new Make.config.template and adapt it to your needs. If you don't want VDR's data
  files to be spread around your system according to the FHS, you can set the
  parameter ONEDIR=1 (using Make.config) to have all files in one /video directory as
  before.
- Fixed the example for cReceiver in PLUGINS.html.
- Fixed sorting recordings in case two folders have the same name, but one of them
  ends in an additional digit, as in "abc" and "abc2" (reported by Andreas Mair).
- Added "repeat" function when using the keyboard to control VDR (thanks to Reinhard
  Nissl).
- The SVDRP command LSTR now knows the additional parameter "path", which can be
  given to get the actual file name of a recording's directory (suggested by
  Stefan Stolz).
- Fixed multiple occurrences of the same directory in the recordings list in case there
  are directories that only differ in non-alphanumeric characters (reported by Andreas
  Mair).
- Absolute jumps when replaying a recording (via the Red key) are now only performed
  if an actual value has been entered (suggested by Ulf Kiener).
- The last replayed recording is now stored in setup.conf, which allows the blue
  "Resume" key in the main menu to work even after a restart of VDR.
- The SVDRP command NEWT no longer checks whether a timer with the given data already
  exists (suggested by Malte Forkel).
- Implemented scaling of SPU bitmaps (thanks to Johann Friedrichs).
- Improved cutting MPEG-2 video (thanks to Sören Moch).
- Reduced the number of retries in cTransfer::Receive() to avoid blocking recordings
  in case the primary device can't handle the current live signal.
2013-01-22 00:35:10 +01:00

360 lines
9.5 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.17 2013/01/12 13:46:00 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.
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 directory environment:
# Use package data if installed...otherwise assume we're under the VDR source directory:
PKGCFG = \$(if \$(VDRDIR),\$(shell pkg-config --variable=\$(1) \$(VDRDIR)/vdr.pc),\$(shell pkg-config --variable=\$(1) vdr || pkg-config --variable=\$(1) ../../../vdr.pc))
LIBDIR = \$(call PKGCFG,libdir)
LOCDIR = \$(call PKGCFG,locdir)
PLGCFG = \$(call PKGCFG,plgcfg)
#
TMPDIR ?= /tmp
### The compiler options:
export CFLAGS = \$(call PKGCFG,cflags)
export CXXFLAGS = \$(call PKGCFG,cxxflags)
### The version number of VDR's plugin API:
APIVERSION = \$(call PKGCFG,apiversion)
### Allow user defined options to overwrite defaults:
-include \$(PLGCFG)
### The name of the distribution archive:
ARCHIVE = \$(PLUGIN)-\$(VERSION)
PACKAGE = vdr-\$(ARCHIVE)
### The name of the shared object file:
SOFILE = libvdr-\$(PLUGIN).so
### Includes and Defines (add further entries here):
INCLUDES +=
DEFINES += -DPLUGIN_NAME_I18N='"\$(PLUGIN)"'
### The object files (add further files here):
OBJS = \$(PLUGIN).o
### The main target:
all: \$(SOFILE) i18n
### Implicit rules:
%.o: %.c
\$(CXX) \$(CXXFLAGS) -c \$(DEFINES) \$(INCLUDES) -o \$\@ \$<
### Dependencies:
MAKEDEP = \$(CXX) -MM -MG
DEPFILE = .dependencies
\$(DEPFILE): Makefile
\@\$(MAKEDEP) \$(CXXFLAGS) \$(DEFINES) \$(INCLUDES) \$(OBJS:%.o=%.c) > \$\@
-include \$(DEPFILE)
### Internationalization (I18N):
PODIR = po
I18Npo = \$(wildcard \$(PODIR)/*.po)
I18Nmo = \$(addsuffix .mo, \$(foreach file, \$(I18Npo), \$(basename \$(file))))
I18Nmsgs = \$(addprefix \$(DESTDIR)\$(LOCDIR)/, \$(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 \$\@ `ls \$^`
%.po: \$(I18Npot)
msgmerge -U --no-wrap --no-location --backup=none -q -N \$\@ \$<
\@touch \$\@
\$(I18Nmsgs): \$(DESTDIR)\$(LOCDIR)/%/LC_MESSAGES/vdr-\$(PLUGIN).mo: \$(PODIR)/%.mo
install -D -m644 \$< \$\@
.PHONY: i18n
i18n: \$(I18Nmo) \$(I18Npot)
install-i18n: \$(I18Nmsgs)
### Targets:
\$(SOFILE): \$(OBJS)
\$(CXX) \$(CXXFLAGS) \$(LDFLAGS) -shared \$(OBJS) -o \$\@
install-lib: \$(SOFILE)
install -D \$^ \$(DESTDIR)\$(LIBDIR)/\$^.\$(APIVERSION)
install: install-lib install-i18n
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 \$(PODIR)/*.mo \$(PODIR)/*.pot
\@-rm -f \$(OBJS) \$(DEPFILE) *.so *.tgz core* *~
};
$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);
}