mirror of
				https://github.com/vdr-projects/vdr.git
				synced 2025-03-01 10:50:46 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			367 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			367 lines
		
	
	
		
			9.7 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 4.4 2020/06/22 15:08:46 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:
 | |
| PKG_CONFIG ?= pkg-config
 | |
| PKGCFG = \$(if \$(VDRDIR),\$(shell $(PKG_CONFIG) --variable=\$(1) \$(VDRDIR)/vdr.pc),\$(shell PKG_CONFIG_PATH="\$\$PKG_CONFIG_PATH:../../.." $(PKG_CONFIG) --variable=\$(1) vdr))
 | |
| 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
 | |
| 	\@echo CC \$\@
 | |
| 	\$(Q)\$(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
 | |
| 	\@echo MO \$\@
 | |
| 	\$(Q)msgfmt -c -o \$\@ \$<
 | |
| 
 | |
| \$(I18Npot): \$(wildcard *.c)
 | |
| 	\@echo GT \$\@
 | |
| 	\$(Q)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)
 | |
| 	\@echo PO \$\@
 | |
| 	\$(Q)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)
 | |
| 	\@echo LD \$\@
 | |
| 	\$(Q)\$(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 "$!";
 | |
| mkdir("$PLUGINDIR/po") || 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 ($FileName, $Content) = @_;
 | |
|   open(FILE, ">$PLUGINDIR/$FileName") || die "$FileName: $!\n";
 | |
|   print FILE $Content;
 | |
|   close(FILE);
 | |
| }
 |