/* * vdr-scripting - A plugin for the Linux Video Disk Recorder * Copyright (c) 2009 Tobias Grimm * * 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. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "ScriptingPlugin.h" #include #include #include "swigrubyrun.h" #include "RubyObjectTracker.h" using namespace std; extern "C" void Init_swig(); extern RubyObjectTracker rubyObjectTracker; VALUE require_pluginmanager_wrap(VALUE arg) { return rb_require("vdr/pluginmanager"); } VALUE new_pluginmanager_wrap(VALUE arg) { VALUE module = rb_const_get(rb_cObject, rb_intern("Vdr")); VALUE klass = rb_const_get(module, rb_intern("PluginManager")); return rb_class_new_instance(0 ,0, klass); } ScriptingPlugin::ScriptingPlugin() { // 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! } ScriptingPlugin::~ScriptingPlugin() { ruby_finalize(); } const char *ScriptingPlugin::CommandLineHelp() { // Return a string that describes all known command line options. return NULL; } bool ScriptingPlugin::ProcessArgs(int argc, char *argv[]) { // Implement command line argument processing here if applicable. return true; } bool ScriptingPlugin::Initialize() { // Initialize any background activities the plugin shall perform. const char* configDir = cPlugin::ConfigDirectory(Name()); RUBY_INIT_STACK; ruby_init(); ruby_init_loadpath(); ruby_incpush(cString::sprintf("%s/lib", configDir)); ruby_script("vdr-plugin-ruby"); Init_swig(); rb_eval_string("STDERR.puts $LOAD_PATH"); int error; VALUE result = rb_protect(require_pluginmanager_wrap, 0, &error); if (IsRubyError(error)) { return true; } //rb_require("vdr/pluginmanager"); VALUE rbPluginManager = rb_protect(new_pluginmanager_wrap, 0, &error); if (IsRubyError(error)) { return true; } if (rbPluginManager == Qnil) { cerr << "rbPluginManger is nil" << endl; } Data_Get_Struct(rbPluginManager, PluginManager, _pluginManager); if (!_pluginManager) { cerr << "no plugin manager" << endl; } return true; } bool ScriptingPlugin::Start() { // Start any background activities the plugin shall perform. return true; } void ScriptingPlugin::Stop() { // Stop any background activities the plugin is performing. } void ScriptingPlugin::Housekeeping() { VALUE gc_wrap(VALUE arg); // Perform any cleanup or other regular tasks. } void ScriptingPlugin::MainThreadHook() { // Perform actions in the context of the main program thread. // WARNING: Use with great care - see PLUGINS.html! } cString ScriptingPlugin::Active() { // Return a message string if shutdown should be postponed return NULL; } time_t ScriptingPlugin::WakeupTime() { // Return custom wakeup time for shutdown script return 0; } cOsdObject *ScriptingPlugin::MainMenuAction() { if (!_pluginManager) { cerr << "NO PLUGINMANAGER" << endl; return NULL; } cOsdObject* osdObject = _pluginManager->PluginMenu(); if (!osdObject) { cerr << "NO MENU" << endl; return NULL; } rubyObjectTracker.KeepRubyObjectAlive(osdObject); return osdObject; } cMenuSetupPage *ScriptingPlugin::SetupMenu() { // Return a setup menu in case the plugin supports one. return NULL; } bool ScriptingPlugin::SetupParse(const char *Name, const char *Value) { // Parse your own setup parameters and store their values. return false; } bool ScriptingPlugin::Service(const char *Id, void *Data) { // Handle custom service requests from other plugins return false; } const char **ScriptingPlugin::SVDRPHelpPages() { // Return help text for SVDRP commands this plugin implements return NULL; } cString ScriptingPlugin::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode) { // Process SVDRP commands this plugin implements return NULL; } VALUE gc_wrap(VALUE arg) { rb_gc(); return Qnil; } void ScriptingPlugin::ForceGarbageCollect() { int status; rb_protect(gc_wrap, 0, &status); // IsRubyError(status); } bool ScriptingPlugin::IsRubyError(int error) { if (error) { VALUE lasterr = rb_gv_get("$!"); VALUE klass = rb_class_path(CLASS_OF(lasterr)); cerr << "class = " << RSTRING(klass)->ptr << endl; VALUE message = rb_obj_as_string(lasterr); cerr << "message = " << RSTRING(message)->ptr << endl; return true; } else { return false; } } VDRPLUGINCREATOR(ScriptingPlugin); // Don't touch this!