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); } }