/* * xine.c: A plugin for the Video Disk Recorder * * See the README file for copyright information and how to reach the author. * * $Id$ */ #include "xineCommon.h" #include #include "xineDevice.h" #include "xineSettings.h" #include "xineSetupPage.h" static const char *VERSION = "0.9.5"; static const char *DESCRIPTION = tr("Software based playback using xine"); //static const char *MAINMENUENTRY = "xine - Toggle prebuffer setting"; class cPluginXine : public cPlugin { private: // Add any member variables or functions you may need here. PluginXine::cXineSettings m_settings; PluginXine::cXineRemote *m_remote; bool m_remoteOn; public: PluginXine::cXineLib *m_xineLib; int m_instanceNo; in_addr_t m_bindIp; int m_bindPort; cPluginXine(void); virtual ~cPluginXine(); virtual const char *Version(void) { return VERSION; } virtual const char *Description(void) { return tr(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); #if APIVERSNUM >= 10347 virtual void MainThreadHook(void); virtual cString Active(void); virtual time_t WakeupTime(void); #endif virtual const char *MainMenuEntry(void);// { return tr(MAINMENUENTRY); } virtual cOsdObject *MainMenuAction(void); virtual cMenuSetupPage *SetupMenu(void); virtual bool SetupParse(const char *Name, const char *Value); #if APIVERSNUM >= 10330 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); #endif }; cPluginXine::cPluginXine(void) : cPlugin() , m_remote(0) , m_remoteOn(false) , m_xineLib(0) , m_instanceNo(-1) , m_bindIp(0) , m_bindPort(0) { // 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! } cPluginXine::~cPluginXine() { // Clean up after yourself! } const char *cPluginXine::CommandLineHelp(void) { //Return a string that describes all known command line options. //" - -- x \n" return " -bIP ip address to bind for socket connections (see -p)\n" " -iN instance number to append to FIFO directory\n" " -p[N] use socket connections on port N (18701)\n" " -q turn off debug messages on console\n" " -r turn on remote (pressing keys in xine controls VDR)\n" #if APIVERSNUM >= 10320 " -s switch to curses skin, while xine is disconnected\n" #endif " -XN default 'SizeX' for GRAB command (720, 1..4096)\n" " -YN default 'SizeY' for GRAB command (576, 1..4096)\n" ; } bool cPluginXine::ProcessArgs(int argc, char *argv[]) { // Implement command line argument processing here if applicable. ::optind = 0; ::opterr = 0; #define INVALID_ARG(fmt, args...) do { esyslog(fmt, ##args); fprintf(stderr, fmt "\n", ##args); } while (false) for (int r = -1; (r = ::getopt(argc, argv, ":b:i:p::qrsX:Y:")) >= 0; ) { switch (r) { case ':': INVALID_ARG("vdr-xine: missing argument for option -%c", ::optopt); return false; case 'b': m_bindIp = ::inet_addr(::optarg); if (m_bindIp == INADDR_NONE) { INVALID_ARG("vdr-xine: invalid argument '%s' for option -%c", ::optarg, r); return false; } break; case 'i': m_instanceNo = ::atoi(::optarg); if (m_instanceNo < 0) { INVALID_ARG("vdr-xine: invalid argument '%s' for option -%c", ::optarg, r); return false; } break; case 'p': if (!::optarg) m_bindPort = 18701; else { m_bindPort = ::atoi(::optarg); if (m_bindPort <= 0) { INVALID_ARG("vdr-xine: invalid argument '%s' for option -%c", ::optarg, r); return false; } } break; case 'r': m_remoteOn = true; break; #if APIVERSNUM >= 10320 case 's': m_settings.SetSwitchSkin(true); break; #endif case 'q': m_settings.SetBeQuiet(true); break; case 'X': { const int X = ::atoi(::optarg); if (X < 1 || X > 4096) { INVALID_ARG("vdr-xine: invalid argument '%s' for option -%c", ::optarg, r); return false; } m_settings.SetDefaultGrabSizeX(X); } break; case 'Y': { const int Y = ::atoi(::optarg); if (Y < 1 || Y > 4096) { INVALID_ARG("vdr-xine: invalid argument '%s' for option -%c", ::optarg, r); return false; } m_settings.SetDefaultGrabSizeY(Y); } break; default: INVALID_ARG("vdr-xine: invalid option -%c", r); return false; } } if (argv[::optind]) { INVALID_ARG("vdr-xine: invalid argument '%s'", argv[::optind]); return false; } #undef INVALID_ARG return true; } bool cPluginXine::Initialize(void) { #if APIVERSNUM < 10507 RegisterI18n(PluginXine::Phrases); #endif // Initialize any background activities the plugin shall perform. m_remote = new PluginXine::cXineRemote(m_remoteOn); if (!m_remote) return false; if (!PluginXine::cXineDevice::Create(this, m_settings, m_remote)) return false; return true; } bool cPluginXine::Start(void) { // Start any background activities the plugin shall perform. if (!PluginXine::cXineDevice::Open()) return false; return true; } void cPluginXine::Stop(void) { PluginXine::cXineDevice::Stop(); } void cPluginXine::Housekeeping(void) { // Perform any cleanup or other regular tasks. } #if APIVERSNUM >= 10347 void cPluginXine::MainThreadHook(void) { // Perform actions in the context of the main program thread. // WARNING: Use with great care - see PLUGINS.html! PluginXine::cXineDevice::MainMenuTrampoline(); } cString cPluginXine::Active(void) { // Return a message string if shutdown should be postponed return NULL; } time_t cPluginXine::WakeupTime(void) { // Return custom wakeup time for shutdown script return 0; } #endif cOsdObject *cPluginXine::MainMenuAction(void) { // Perform the action when selected from the main VDR menu. #if APIVERSNUM < 10347 PluginXine::cXineDevice::MainMenuTrampoline(); #endif return NULL; } cMenuSetupPage *cPluginXine::SetupMenu(void) { // Return a setup menu in case the plugin supports one. return new PluginXine::cXineSetupPage(m_xineLib, m_settings); } bool cPluginXine::SetupParse(const char *Name, const char *Value) { // Parse your own setup parameters and store their values. return m_settings.SetupParse(Name, Value); } #if APIVERSNUM >= 10330 bool cPluginXine::Service(const char *Id, void *Data) { // Handle custom service requests from other plugins return cPlugin::Service(Id, Data); } const char **cPluginXine::SVDRPHelpPages(void) { // Return help text for SVDRP commands this plugin implements return cPlugin::SVDRPHelpPages(); } cString cPluginXine::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode) { // Process SVDRP commands this plugin implements return cPlugin::SVDRPCommand(Command, Option, ReplyCode); } #endif const char *cPluginXine::MainMenuEntry(void) { // return m_settings.GetMainMenuEntry(); return 0; } namespace PluginXine { int GetBindIp(cPlugin *const plugin) { return ((cPluginXine *)plugin)->m_bindIp; } int GetBindPort(cPlugin *const plugin) { return ((cPluginXine *)plugin)->m_bindPort; } int GetInstanceNo(cPlugin *const plugin) { return ((cPluginXine *)plugin)->m_instanceNo; } cXineLib *&GetXineLib(cPlugin *const plugin) { return ((cPluginXine *)plugin)->m_xineLib; } } VDRPLUGINCREATOR(cPluginXine); // Don't touch this!