I am developing a small plugin, very similar to the nfs_mount of Mechatron. The objective is to learn more about plugins. I facing very strange behaviour on the latest official release 107_4.
When the plugin is invoked, the whole DB crashs, and reboots. By the way, I also made the following:
cd /var/tuxbox/plugins
ln -s /lib/libgcc_s.so.1 libgcc_s_nof.so.1
as it seems that the nof library is needed by my plugin.
When I try the same plugin on one of the customized images based on 107_4, the plugin starts, and I can mount my laptop HD, however, when ending the plugin, the dialog box do not disappear, but goes into the background, and when invoked again, I get an error saying "someone has stolen the focus", and I have to reboot the DB.
I guess that the code is fine, but I suspect that the make file build options are not correct.
Can anyone help me getting my first plugin working properly.
I tried to attach a zip file with the source of the plugin, and the makefile I used to build it, but did not find any attach option. So, I am adding here the files in text mode.
Any help is very much appreciated.
Note: Is there a way to kill an invoked plugin, without killing the whole engima. I am currently in an experiemental phase, I do not want to reboot my DB every 5 mins.
Also, I am trying to update my CDK tree on my machine, however, I am getting all the time, connection refused from the CVS server. Is there something that changed?
Plugin source
Code: Alles auswählen
/* An NFS mount plugin based on same idea from Mechatron */
#include <stdio.h>
#include <plugin.h>
#include <lib/gui/ewindow.h>
#include <lib/gui/ebutton.h>
#include <lib/gui/emessage.h>
#include <lib/gui/textinput.h>
#include <lib/gui/combobox.h>
#include <lib/gui/statusbar.h>
#include <lib/gui/eskin.h>
// plugin entry point, declared to use C calling convention
extern "C" int plugin_exec( PluginParam *par );
// mouter dialog. based on a eWindow, and thus is toplevel and has decoration.
class mountDialog: public eWindow
{
private:
// Private class attributes:
eComboBox *eConfCombo;
// two buttons, one for mount and another one for un-mount.
eButton *bt_mount, *bt_unmount, *bt_save;
// Labels to display status information.
eLabel *lb_config, *lb_IP, *lb_dir, *lb_mount, *lb_options, *lb_status;
// Input fields for the user to enter NFS mounting information
eTextInputField *inp_IP, *inp_dir, *inp_mount, *inp_options;
eStatusBar *st_help;
// Private methods:
void mount_dev(void);
void unmount_dev(void);
void save_conf(void);
public:
// the constructor.
mountDialog();
// the destructor.
~mountDialog();
};
// Plugin entry point.
int plugin_exec( PluginParam *par )
{
// NFS mount dialog instance.
mountDialog dlg;
// show the dialog...
dlg.show();
// give control to dialog.. (the dialog is modal!)
int result=dlg.exec();
// and after it, hide it again.
dlg.hide();
// if the result of the dialog is non-zero, show this warning.
if (result)
{
eMessageBox msg(_("Leaving Mounter dialog!"), _("User Abort"), eMessageBox::iconWarning|eMessageBox::btOK);
msg.show(); msg.exec(); msg.hide();
}
return result;
}
// mountDialog Methods implementations
// mountDialog constructor implementation
mountDialog::mountDialog(): eWindow(1)
{
// move dialog to point 160,75 (0,0 is the top left corner of the screen)
cmove(ePoint(160, 75));
// ...and give it appropriate size on the screen.
cresize(eSize(360, 390));
// set a title.
setText("MOUNTER");
// Create configuration selection combobox Label
lb_config=new eLabel(this);
lb_config->move(ePoint(10, 20));
lb_config->resize(eSize(150, 30));
lb_config->setText("Configuration");
// Create configuration selection combobox
eConfCombo = new eComboBox(this);
eConfCombo->move(ePoint(150,20));
eConfCombo->resize(eSize(150,30));
eConfCombo->loadDeco();
eConfCombo->setHelpText(_("Select NFS configuration"));
eConfCombo->setCurrent( new eListBoxEntryText( *eConfCombo, "Internal Hard Disk", (void*) 1) );
eConfCombo->setCurrent( new eListBoxEntryText( *eConfCombo, "External Hard Disk (NFS)", (void*) 2) );
eConfCombo->setCurrent( new eListBoxEntryText( *eConfCombo, "USB Memory Stick", (void*) 3) );
eConfCombo->setCurrent( new eListBoxEntryText( *eConfCombo, "Compact Flash", (void*) 4) );
eConfCombo->setCurrent( new eListBoxEntryText( *eConfCombo, "Others", (void*) 5) );
// Create user input text fields with corresponding labels
// Create NFS IP Label
lb_IP=new eLabel(this);
lb_IP->move(ePoint(10, 70));
lb_IP->resize(eSize(150, 30));
lb_IP->setText("NFS-Server IP");
// Create NFS IP InputText Field
inp_IP=new eTextInputField(this);
inp_IP->setName("inputIPfield");
inp_IP->setMaxChars(15);
inp_IP->setUseableChars(".1234567890");
inp_IP->move(ePoint(150, 70));
inp_IP->resize(eSize(200, 30));
inp_IP->loadDeco();
inp_IP->setHelpText("Enter you PC IP address");
inp_IP->setEditHelpText("Valid values (0..9 and .)");
inp_IP->setText("192.168.0.1"); //Temporary
// Create NFS directory Label
lb_dir=new eLabel(this);
lb_dir->move(ePoint(10, 120));
lb_dir->resize(eSize(150, 30));
lb_dir->setText("NFS-Directory");
// Create NFS directory InputText Field
inp_dir=new eTextInputField(this);
inp_dir->setName("inputDirfield");
inp_dir->setMaxChars(20);
inp_dir->move(ePoint(150, 120));
inp_dir->resize(eSize(200, 30));
inp_dir->loadDeco();
inp_dir->setHelpText("Enter the shared PC directory");
inp_dir->setEditHelpText("Example: /dreambox");
inp_dir->setText("/dreambox"); //Temporary
// Create Mountpoint Label
lb_mount=new eLabel(this);
lb_mount->move(ePoint(10, 170));
lb_mount->resize(eSize(150, 30));
lb_mount->setText("Mountpoint");
// Create Mountpoint InputText Field
inp_mount=new eTextInputField(this);
inp_mount->setName("inputMountfield");
inp_mount->setMaxChars(20);
inp_mount->move(ePoint(150, 170));
inp_mount->resize(eSize(200, 30));
inp_mount->loadDeco();
inp_mount->setHelpText("Enter the mounting point on your DB");
inp_mount->setEditHelpText("Example: /hdd");
inp_mount->setText("/hdd"); //Temporary
// Create Options Label
lb_options=new eLabel(this);
lb_options->move(ePoint(10, 220));
lb_options->resize(eSize(150, 30));
lb_options->setText("Options");
// Create Option InputText Field
inp_options=new eTextInputField(this);
inp_options->setName("inputOptionsfield");
inp_options->setMaxChars(20);
inp_options->move(ePoint(150, 220));
inp_options->resize(eSize(200, 30));
inp_options->loadDeco();
inp_options->setHelpText("Enter the mounting options");
inp_options->setEditHelpText("Example: -t nfs -o nolock");
inp_options->setText("-t nfs -o nolock"); //Temporary
// Create the Mount button
bt_mount=new eButton(this);
bt_mount->move(ePoint(10, 270));
bt_mount->resize(eSize(110, 30));
// set the shortcut action as the green button.
bt_mount->setShortcut("green");
bt_mount->setShortcutPixmap("green");
// load some decoration (border)
bt_mount->loadDeco();
// set Text
bt_mount->setText("Mount");
bt_mount->setHelpText("Click to mount device");
// "connect" the button. if the user pressed this button (either by selecting it and pressing
// Mount or by pressing green) the button should do the following:
//
//
CONNECT(bt_mount->selected, mountDialog::mount_dev);
// Create the Unmount button
bt_unmount=new eButton(this);
bt_unmount->move(ePoint(125, 270));
bt_unmount->resize(eSize(110, 30));
// set the shortcut action as the red button.
bt_unmount->setShortcut("red");
bt_unmount->setShortcutPixmap("red");
// load some decoration (border)
bt_unmount->loadDeco();
// set Text
bt_unmount->setText("Unmount");
bt_unmount->setHelpText("Click to unmount device");
// "connect" the button. if the user pressed this button (either by selecting it and pressing
// Unmount or by pressing red) the button should do the following:
//
//
CONNECT(bt_unmount->selected, mountDialog::unmount_dev);
// Create the Save button
bt_save=new eButton(this);
bt_save->move(ePoint(240, 270));
bt_save->resize(eSize(110, 30));
// set the shortcut action as the red button.
bt_save->setShortcut("yellow");
bt_save->setShortcutPixmap("yellow");
// load some decoration (border)
bt_save->loadDeco();
// set Text
bt_save->setText("Save");
bt_save->setHelpText("Click to save this configuration");
// "connect" the button. if the user pressed this button (either by selecting it and pressing
// Unmount or by pressing red) the button should do the following:
//
//
CONNECT(bt_save->selected, mountDialog::save_conf);
// Create the status label
lb_status=new eLabel(this);
lb_status->move(ePoint(95, 320));
lb_status->resize(eSize(170, 30));
lb_status->loadDeco();
lb_status->setProperty(eString().sprintf("align"), eString().sprintf("center"));
lb_status->setText("???????");
// Create a status bar at the bottom of our dialog to display the help
st_help=new eStatusBar(this);
st_help->move( ePoint(0, 360) );
st_help->resize( eSize(360, 30) );
st_help->loadDeco();
setHelpID(93);
// Set the focus to the Configuration Combobox
this->setFocus(eConfCombo);
}
// The dialog destructor implementation
mountDialog::~mountDialog()
{
// we have to do almost nothing here. all widgets are automatically removed
// since they are children of the main dialog. the eWidget-destructor will do to this.
}
void mountDialog::mount_dev(void)
{
eString in_IP, in_dir, in_mount, in_options, mount_cmd;
int ret;
in_IP = inp_IP->getText();
in_dir = inp_dir->getText();
in_mount = inp_mount->getText();
in_options = inp_options->getText();
mount_cmd = "mount "+in_options+" \42"+in_IP+"\42:"+in_dir+" "+in_mount;
// eMessageBox msg(mount_cmd,"Mount Command", eMessageBox::iconWarning|eMessageBox::btOK);
// msg.show(); msg.exec(); msg.hide();
// ret = 0;
ret = system(mount_cmd.c_str()); //c.str to convert sString to cont *char needed for system()
if (ret == 0 ) { //mounting was successfull
lb_status->setText("mounted!");
} else {
hide();
eMessageBox msg(eString().sprintf("Error in mounting, return code = %d",ret),"Mount Status", eMessageBox::iconWarning|eMessageBox::btOK);
msg.show(); msg.exec(); msg.hide();
show();
}
}
void mountDialog::unmount_dev(void)
{
eString umount_cmd, in_mount;
int ret;
in_mount = inp_mount->getText();
umount_cmd = "umount "+in_mount;
ret = system(umount_cmd.c_str());
if (ret == 0 ) { //mounting was successfull
lb_status->setText("un-mounted!");
} else {
hide();
eMessageBox msg(eString().sprintf("Error in un-mounting, return code = %d",ret),"Un-mount Status", eMessageBox::iconWarning|eMessageBox::btOK);
msg.show(); msg.exec(); msg.hide();
show();
}
}
void mountDialog::save_conf(void)
{
}
makefile
Code: Alles auswählen
CDK_SRC = /home/tuxbox-cvs
CDKROOT = /home/dbox2/cdkroot
BOXBIN = /home/dbox2/cdk/bin
CXX = $(BOXBIN)/powerpc-tuxbox-linux-gnu-g++
STRIP = $(BOXBIN)/powerpc-tuxbox-linux-gnu-strip
INCLUDES = -I$(CDK_SRC)/apps/tuxbox/enigma/include -I$(CDKROOT)/include -I$(CDKROOT)/include/sigc++-1.2 -I$(CDKROOT)/lib/sigc++-1.2/include -I$(CDK_SRC)/apps/tuxbox/enigma -I$(CDK_SRC)/apps/misc/libs/libxmltree -I$(CDK_SRC)/apps/tuxbox/plugins/include -I$(CDKROOT)/include/freetype2 -I. -I$(CDK_SRC)/apps/tuxbox/enigma/src
# this is your original
#CFLAGS = -DEMU_PLUGIN $(INCLUDES) -fno-rtti -fno-exceptions -Wall -O2 -mcpu=823 -msoft-float -mmultiple -mstring -g -ggdb3 -pipe
CFLAGS = -DEMU_PLUGIN $(INCLUDES) -fno-rtti -fno-exceptions -Wall -Os -mcpu=823 -mmultiple -meabi -mstring -pipe
LINK_OPTIONS = -shared -Wall -O2 -mcpu=823 -msoft-float -mmultiple -mstring -g -ggdb3 -pipe -Xlinker -R -Xlinker /var/tuxbox/plugins
NAME=nfsm
OBJECTS = nfsm.o
.cpp.o:
$(CXX) $(CFLAGS) -c -o $@ $<
nfsm.o: nfsm.cpp
$(CXX) $(CFLAGS) -c -o $@ nfsm.cpp
all: $(NAME).so
$(NAME).so: $(OBJECTS)
$(CXX) $(LINK_OPTIONS) -o $(NAME).so $(OBJECTS)
$(STRIP) -s $(NAME).so
clean:
rm -rf *.o