The fof source code contains the following files :
Fof is highly customizable and it's relatively easy to add new functionnalities from the developer's point of view. This is not a tutorial about the command creation, it's just an overview of the process.
The following sections show the different steps needed to add a new command. We have decided to use the untar command which is a representative and easy to implement command.
The first thing to do is to add a menu entry in the menu hierarchy.
void InitInterface(int argc, char **argv)
{
/*** interface creation (many lines) ***/
/* Archive Menu */
w_temp4=XmCreatePulldownMenu(w_menubar, "ArcMenu", NULL, 0);
w_temp3=XtVaCreateManagedWidget("ArcMenuButton", xmCascadeButtonWidgetClass,
w_menubar, XmNsubMenuId, w_temp4, NULL);
/*** preceeding menu entries ***/
/*** ADD THIS ***/
w_temp5=XtVaCreateManagedWidget("UnTarButton", xmPushButtonWidgetClass, w_temp4, NULL);
/*** following entries ***/
w_temp5=XtVaCreateManagedWidget("MenuSeparator", xmSeparatorWidgetClass, w_temp4, NULL);
/*** rest of the interface creation ***/
}
void UnTarButtonCB(Widget w_button, XtPointer app_data, XtPointer widget_data)
{
Bool warning;
GetVarBool("NoSelectionWarning", &warning);
if(warning && SelectFileViewList==NULL) NO_SELECTION_MESSAGE;
else ArchiveUnTarRoutine();
}
/* ArchiveUnTar Button */
w = NULL;
w = XtNameToWidget(W_App, "*UnTarButton");
if(w==NULL) FatalError("menu.c","InstallDefaultMenuCB","Unable to retrieve UnTarButton widget");
XtAddCallback(w, XmNactivateCallback, UnTarButtonCB, NULL);
The next step is more complex, you have to build the dialog used to set the parameters of the command :
This is done in dialog.c :
void ArchiveUnTarInitDialog()
{
Widget w_temp;
Widget w_separator1, w_cancelbtn;
/* Create the dialog */
W_UnTarDialog=XmCreateFormDialog(W_MainWindow, "UnTarDialog", NULL, 0);
/* Action zone */
W_Init[0] = XtVaCreateManagedWidget("UnTarHelpButton", xmPushButtonWidgetClass, W_UnTarDialog,
XmNbottomAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_FORM,
NULL);
w_separator1 = XtVaCreateManagedWidget("UnTarSeparator1", xmSeparatorWidgetClass, W_UnTarDialog,
XmNbottomAttachment, XmATTACH_WIDGET,
XmNbottomWidget, W_Init[0],
XmNleftAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_FORM,
NULL);
w_cancelbtn = XtVaCreateManagedWidget("UnTarCancelButton", xmPushButtonWidgetClass, W_UnTarDialog,
XmNbottomAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_WIDGET,
XmNrightWidget, W_Init[0],
NULL);
W_Init[1] = XtVaCreateManagedWidget("UnTarOkButton", xmPushButtonWidgetClass, W_UnTarDialog,
XmNbottomAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_WIDGET,
XmNrightWidget, w_cancelbtn,
NULL);
/* Option box frame */
W_Init[0] = XtVaCreateManagedWidget("UnTarOptionBoxFrame", xmFrameWidgetClass, W_UnTarDialog,
XmNleftAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_FORM,
XmNbottomAttachment, XmATTACH_WIDGET,
XmNbottomWidget, w_separator1,
NULL);
W_Init[1] = XtVaCreateManagedWidget("UnTarOptionBoxLabel", xmLabelWidgetClass, W_Init[0],
XmNchildType, XmFRAME_TITLE_CHILD,
NULL);
W_Init[1] = XtVaCreateManagedWidget("UnTarToggleButton", xmToggleButtonWidgetClass, W_Init[0],
XmNchildType, XmFRAME_WORKAREA_CHILD,
NULL);
/* filename frame */
W_Init[0] = XtVaCreateManagedWidget("UnTarFilenameFrame", xmFrameWidgetClass, W_UnTarDialog,
XmNleftAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_FORM,
XmNtopAttachment, XmATTACH_FORM,
XmNbottomAttachment, XmATTACH_WIDGET,
XmNbottomWidget, W_Init[0],
NULL);
W_Init[1] = XtVaCreateManagedWidget("UnTarFilenameLabel", xmLabelWidgetClass, W_Init[0],
XmNchildType, XmFRAME_TITLE_CHILD,
NULL);
W_Init[1] = XtVaCreateManagedWidget("UnTarFilenameText", xmTextFieldWidgetClass, W_Init[0],
XmNchildType, XmFRAME_WORKAREA_CHILD,
XmNeditable, False,
XmNcursorPositionVisible, False,
NULL);
/* hard coded values for the dialog */
XtVaSetValues(W_UnTarDialog,
XmNdefaultButton, w_cancelbtn,
XmNcancelButton, w_cancelbtn,
XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL,
XmNresizePolicy, XmRESIZE_GROW,
XmNautoUnmanage, False,
NULL);
/* Remove decorations for dialogs */
XtVaSetValues(XtParent(W_UnTarDialog),
XmNmwmDecorations, MWM_DECOR_ALL | MWM_DECOR_MAXIMIZE | MWM_DECOR_MINIMIZE | MWM_DECOR_MENU,
NULL);
/* Create callbacks */
/* Ok Button */
w_temp = NULL;
w_temp = XtNameToWidget(W_UnTarDialog, "*UnTarOkButton");
if(w_temp==NULL) FatalError("dialogs.c","ArchiveUnTarInitDialog","Unable to retrieve Ok Button widget");
XtAddCallback(w_temp, XmNactivateCallback, ArchiveUnTarOkButtonCB, NULL);
/* Cancel Button */
w_temp = NULL;
w_temp = XtNameToWidget(W_UnTarDialog, "*UnTarCancelButton");
if(w_temp==NULL) FatalError("dialogs.c","ArchiveUnTarInitDialog","Unable to retrieve Cancel Button widget");
XtAddCallback(w_temp, XmNactivateCallback, ArchiveUnTarCancelButtonCB, NULL);
/* Help Button */
w_temp = NULL;
w_temp = XtNameToWidget(W_UnTarDialog, "*UnTarHelpButton");
if(w_temp==NULL) FatalError("dialogs.c","ArchiveUnTarInitDialog","Unable to retrieve Help Button widget");
XtAddCallback(w_temp, XmNactivateCallback, ArchiveUnTarHelpButtonCB, NULL);
}
The callbacks used for the "Ok", "Cancel" and "Help" buttons in the case of the untar command follow :
void ArchiveUnTarOkButtonCB(Widget w_button, XtPointer app_data, XtPointer widget_data)
{
char *destfile;
Widget w_temp;
Bool gunzip;
/* Get Destination file */
w_temp = XtNameToWidget(W_UnTarDialog, "*UnTarFilenameText");
destfile = XmTextGetString(w_temp);
w_temp = XtNameToWidget(W_UnTarDialog, "*UnTarToggleButton");
gunzip = XmToggleButtonGetState(w_temp);
XtUnmanageChild(W_UnTarDialog);
ArchiveUnTarCommandRoutine(destfile, gunzip);
if(destfile!=NULL) XtFree(destfile);
BlockRefreshRoutine=0;
}
void ArchiveUnTarCancelButtonCB(Widget w_button, XtPointer app_data, XtPointer widget_data)
{
XtUnmanageChild(W_UnTarDialog);
BlockRefreshRoutine=0;
}
void ArchiveUnTarHelpButtonCB(Widget w_button, XtPointer app_data, XtPointer widget_data)
{
}
NOTE : The help functionalities are not yet implemented.
The following function is called when the used select the menu entry with a non-NULL selection.
void ArchiveUnTarRoutine(void)
{
Widget w_temp;
if(W_UnTarDialog==NULL) ArchiveUnTarInitDialog();
BlockRefreshRoutine=1;
w_temp = XtNameToWidget(W_UnTarDialog, "*UnTarFilenameText");
XmTextSetString(w_temp, SelectFileViewList->filenode->file.name);
XtManageChild(W_UnTarDialog);
}
This routine, extracted from command.c run the command using the status dialog:
void ArchiveUnTarCommandRoutine(char *DestFile, Bool gunzip)
{
char *commandstring;
TExecList execlist;
if(!gunzip) {
commandstring = XtMalloc(sizeof(char)*(14+strlen(DestFile)));
strcpy(commandstring, "tar -x -f ");
/* Create source filename */
strcat(commandstring, DestFile);
execlist.interactive=0;
execlist.nb_commands=1;
execlist.headerstring = XtMalloc(strlen("Unarchive files")+1);
strcpy(execlist.headerstring, "Unarchive files");
execlist.command = (char **) XtMalloc(sizeof(char *));
execlist.command[0]=commandstring;
execlist.usercommand=0;
GeneralExecCommand2(execlist);
} else {
commandstring = XtMalloc(sizeof(char)*(17+strlen(DestFile)));
strcpy(commandstring, "tar -x -z -f ");
/* Create source filename */
strcat(commandstring, DestFile);
execlist.interactive=0;
execlist.nb_commands=1;
execlist.headerstring = XtMalloc(strlen("Unarchive files")+1);
strcpy(execlist.headerstring, "Unarchive files");
execlist.command = (char **) XtMalloc(sizeof(char *));
execlist.command[0]=commandstring;
execlist.usercommand=0;
GeneralExecCommand2(execlist);
}
}