home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume4 / xf / part02 / x.c < prev   
Encoding:
C/C++ Source or Header  |  1989-09-07  |  20.5 KB  |  800 lines

  1. /* 
  2.  * x.c --
  3.  *
  4.  *    Routines that handle the window interface.
  5.  *
  6.  * Copyright 1989 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  *
  15.  * Author: Gary Shea, UC Berkeley, Dept. of Chemistry
  16.  */
  17.  
  18. static char rcsid[] = "$Header: x.c,v 1.3 89/07/18 00:04:39 garys Exp $";
  19.  
  20. #include "xf.h"
  21.  
  22. /* Local declarations. */
  23.  
  24. static void    BuildDialogBox( void ) ;
  25.  
  26. static XtSetDataStruct    **BuildSetData( DirTree *dirPtr ) ;
  27.  
  28. static void    ConfirmButtonPushed( Widget w,
  29.             caddr_t client_data, caddr_t call_data ) ;
  30. static void    DoneButtonPushed( Widget w,
  31.             caddr_t client_data, caddr_t call_data ) ;
  32. static void    EnterFileName( Widget w,
  33.             caddr_t client_data, caddr_t call_data ) ;
  34. static void    OpenDirDown( Widget w,
  35.             caddr_t client_data, caddr_t call_data ) ;
  36. static void    OutputFileNames( DirTree *dirTreePtr,
  37.             void *clientData ) ;
  38. static void    QuitButtonPushed( Widget w,
  39.             caddr_t client_data, caddr_t call_data ) ;
  40. static void    UpButtonPushed( Widget w,
  41.             caddr_t client_data, caddr_t call_data ) ;
  42.  
  43. /* Information about the dialog box where file names are entered. */
  44.  
  45. static struct
  46. {
  47.     Widget    shellW ;
  48.     Widget    dialogW ;
  49.     Widget    textW ;
  50.     Widget    labelW ;
  51.     Widget    confComW ;
  52.     char    fileName[ MAXPATHLEN + 1 ] ;
  53. }
  54. dialogBox ;
  55.  
  56.  
  57. /*
  58.  *----------------------------------------------------------------------
  59.  *
  60.  * BuildDialogBox --
  61.  *
  62.  *    Create (realize but don't display) the dialog box that
  63.  *    the user can enter a filename into.  It is displayed
  64.  *    when XtPopup is called.
  65.  *
  66.  * Results:
  67.  *    None.
  68.  *
  69.  * Side effects:
  70.  *    A shell widget and dialog box are instantiated, but not displayed.
  71.  *
  72.  *  Arguments:
  73.  *    None.
  74.  *
  75.  *----------------------------------------------------------------------
  76.  */
  77.  
  78. static void
  79. BuildDialogBox( void )
  80. {
  81.     char    errLine[ ERRLINE_LEN ] ;
  82.     char    *pLocName = "BuildDialogBox()" ;
  83.  
  84.     int        n ;
  85.     Arg        args[ 10 ] ;
  86.  
  87.     XtCallbackRec    callbacks[ 5 ] = { {NULL,NULL}, {NULL,NULL} } ;
  88.  
  89.     char    *label =
  90.     "Enter File Name                                                    " ;
  91.  
  92. #ifdef DEBUG
  93.     fprintf ( pErrFp, "\n%s:\n", pLocName ) ;
  94. #endif
  95.  
  96.     /* Make a pop up shell to hold the mess. */
  97.  
  98.     dialogBox.shellW = XtCreatePopupShell ( "Enter Directory Name",
  99.     applicationShellWidgetClass, topLevelW, NULL, 0 ) ;
  100.  
  101.     /* Make the Dialog widget that will get popped up.
  102.     *  Be sure the fileName string is blank initially.
  103.     */
  104.  
  105.     strcpy ( dialogBox.fileName, "" ) ;
  106.  
  107.     n = 0 ;
  108. #ifdef NOAPPDEFAULTS
  109.     XtSetArg( args[n], XtNlabel, label ) ; ++n ;
  110.     XtSetArg( args[n], XtNmaximumLength, MAXPATHLEN ) ; ++n ;
  111. #endif
  112.     XtSetArg( args[n], XtNvalue, dialogBox.fileName ) ; ++n ;
  113.     dialogBox.dialogW = XtCreateManagedWidget ( "dialog", dialogWidgetClass,
  114.             dialogBox.shellW, args, n ) ;
  115.  
  116.     /* Find the id of the Text widget holding the string. */
  117.  
  118.     dialogBox.textW = XtNameToWidget ( dialogBox.dialogW, "value" ) ;
  119.     dialogBox.labelW = XtNameToWidget ( dialogBox.dialogW, "label" ) ;
  120.  
  121. #ifdef DEBUG
  122.     fprintf ( pErrFp, "\tdialogW=%d, textW=%d, labelW=%d\n",
  123.     dialogBox.dialogW, dialogBox.textW, dialogBox.labelW ) ;
  124. #endif
  125.  
  126.     callbacks[0].callback = ConfirmButtonPushed ;
  127.     n = 0 ;
  128.     XtSetArg( args[n], XtNcallback, callbacks ) ; ++n ;
  129. #ifdef NOAPPDEFAULTS
  130.     XtSetArg( args[n], XtNlabel, "Confirm" ) ; ++n ;
  131. #endif
  132.     dialogBox.confComW = XtCreateManagedWidget ( "confirm", commandWidgetClass,
  133.             dialogBox.dialogW, args, n ) ;
  134.     callbacks[0].callback = NULL ;
  135.  
  136.     /* Allow the user to short-circuit the stupid Dialog widget. */
  137.  
  138.     XtInstallAccelerators ( dialogBox.textW, dialogBox.confComW );
  139.     XtRealizeWidget ( dialogBox.shellW ) ;
  140. }
  141.  
  142.  
  143. /*
  144.  *----------------------------------------------------------------------
  145.  *
  146.  * BuildDirBox --
  147.  *
  148.  *    Make the widget-conglomerate that will display one dir's
  149.  *    information.
  150.  *
  151.  * Results:
  152.  *    The id of the applicationShellWidget that holds everything.
  153.  *
  154.  * Side effects:
  155.  *    Lots.
  156.  *
  157.  *  Arguments:
  158.  *    dirPtr - DirTree that holds this dir box's info.
  159.  *
  160.  *----------------------------------------------------------------------
  161.  */
  162.  
  163. Widget
  164. BuildDirBox( DirTree *dirPtr )
  165. {
  166.     char    errLine[ ERRLINE_LEN ] ;
  167.     char    *pLocName = "BuildDirBox()" ;
  168.  
  169.     int            n ;
  170.     Arg            args[ 10 ] ;
  171.     XtCallbackRec    callbacks[ 5 ] = { {NULL,NULL}, {NULL,NULL} } ;
  172.  
  173.  
  174. #ifdef DEBUG
  175.     fprintf( pErrFp, "\n%s:\n", pLocName );
  176. #endif
  177.  
  178.     /* Make a pop up shell to hold the mess. */
  179.  
  180.     dirPtr->shellW = XtCreatePopupShell ( StrSave( dirPtr->fullName ),
  181.     applicationShellWidgetClass, topLevelW, NULL, 0 ) ;
  182.  
  183.     /* Make the Frame widget that will hold everyone. */
  184.  
  185.     dirPtr->frameW = XtCreateManagedWidget ( "form", formWidgetClass,
  186.             dirPtr->shellW, NULL, 0 ) ;
  187.  
  188.     /* Make the Label for the top. */
  189.  
  190.     n = 0 ;
  191.     XtSetArg( args[n], XtNlabel, dirPtr->fullName ) ; ++n ;
  192.     dirPtr->labelW = XtCreateManagedWidget ( "label", labelWidgetClass,
  193.             dirPtr->frameW, args, n ) ;
  194.  
  195.     /* Make the Set to put in the middle.  First get the
  196.     *  set of stuff to put in it.
  197.     */
  198.  
  199.     if ( ( dirPtr->setPtr = BuildSetData( dirPtr ) ) == NULL )
  200.     FatalError ( pLocName, "Null BuildSetData()" ) ;
  201.  
  202.     callbacks[0].callback = OpenDirDown ;
  203.     n = 0 ;
  204. #ifdef NOAPPDEFAULTS
  205.     XtSetArg( args[n], XtNdefaultColumns, 5 ) ; ++n ;
  206.     XtSetArg( args[n], XtNcolumnSpacing, 20 ) ; ++n ;
  207.     XtSetArg( args[n], XtNfromVert, dirPtr->labelW ) ; ++n ;
  208. #endif
  209.     XtSetArg( args[n], XtNset, dirPtr->setPtr ) ; ++n ;
  210.     XtSetArg( args[n], XtNnumberStrings, dirPtr->fileCnt ) ; ++n ;
  211.     XtSetArg( args[n], XtNcallbackB, callbacks ) ; ++n ;
  212.     dirPtr->setW = XtCreateManagedWidget ( "set", setWidgetClass,
  213.             dirPtr->frameW, args, n ) ;
  214.     callbacks[0].callback = NULL ;
  215.  
  216.     /* Make the Up button on the far left. */
  217.  
  218.     callbacks[0].callback = UpButtonPushed ;
  219.     n = 0 ;
  220. #ifdef NOAPPDEFAULTS
  221.     XtSetArg( args[n], XtNlabel, "Up" ) ; ++n ;
  222.     XtSetArg( args[n], XtNfromVert, dirPtr->setW ) ; ++n ;
  223.     XtSetArg( args[n], XtNleft, XtChainLeft ) ; ++n ;
  224.     XtSetArg( args[n], XtNright, XtChainLeft ) ; ++n ;
  225. #endif
  226.     XtSetArg( args[n], XtNcallback, callbacks ) ; ++n ;
  227.     dirPtr->upComW = XtCreateManagedWidget ( "up", commandWidgetClass,
  228.             dirPtr->frameW, args, n ) ;
  229.     callbacks[0].callback = NULL ;
  230.  
  231.     /* Put the Quit button in the middle. */
  232.  
  233.     callbacks[0].callback = QuitButtonPushed ;
  234.     n = 0 ;
  235. #ifdef NOAPPDEFAULTS
  236.     XtSetArg( args[n], XtNlabel, "Quit" ) ; ++n ;
  237.     XtSetArg( args[n], XtNfromVert, dirPtr->setW ) ; ++n ;
  238.     XtSetArg( args[n], XtNfromHoriz, dirPtr->upComW ) ; ++n ;
  239.     XtSetArg( args[n], XtNleft, XtChainLeft ) ; ++n ;
  240.     XtSetArg( args[n], XtNright, XtChainRight ) ; ++n ;
  241. #endif
  242.     XtSetArg( args[n], XtNcallback, callbacks ) ; ++n ;
  243.     dirPtr->quitComW = XtCreateManagedWidget ( "quit", commandWidgetClass,
  244.             dirPtr->frameW, args, n ) ;
  245.     callbacks[0].callback = NULL ;
  246.  
  247.     /* Put the Done button in the middle too. */
  248.  
  249.     callbacks[0].callback = DoneButtonPushed ;
  250.     n = 0 ;
  251. #ifdef NOAPPDEFAULTS
  252.     XtSetArg( args[n], XtNlabel, "Done" ) ; ++n ;
  253.     XtSetArg( args[n], XtNfromVert, dirPtr->setW ) ; ++n ;
  254.     XtSetArg( args[n], XtNfromHoriz, dirPtr->quitComW ) ; ++n ;
  255.     XtSetArg( args[n], XtNleft, XtChainLeft ) ; ++n ;
  256.     XtSetArg( args[n], XtNright, XtChainRight ) ; ++n ;
  257. #endif
  258.     XtSetArg( args[n], XtNcallback, callbacks ) ; ++n ;
  259.     dirPtr->doneComW = XtCreateManagedWidget ( "done", commandWidgetClass,
  260.             dirPtr->frameW, args, n ) ;
  261.     callbacks[0].callback = NULL ;
  262.  
  263.     /* Put the fileName button to the right. */
  264.  
  265.     callbacks[0].callback = EnterFileName ;
  266.     n = 0 ;
  267. #ifdef NOAPPDEFAULTS
  268.     XtSetArg( args[n], XtNlabel, "Enter Filename" ) ; ++n ;
  269.     XtSetArg( args[n], XtNfromVert, dirPtr->setW ) ; ++n ;
  270.     XtSetArg( args[n], XtNfromHoriz, dirPtr->doneComW ) ; ++n ;
  271.     XtSetArg( args[n], XtNleft, XtChainRight ) ; ++n ;
  272.     XtSetArg( args[n], XtNright, XtChainRight ) ; ++n ;
  273. #endif
  274.     XtSetArg( args[n], XtNcallback, callbacks ) ; ++n ;
  275.     dirPtr->fileComW = XtCreateManagedWidget ( "dir_name", commandWidgetClass,
  276.             dirPtr->frameW, args, n ) ;
  277.     callbacks[0].callback = NULL ;
  278.  
  279.     XtPopup ( dirPtr->shellW, XtGrabNone ) ;
  280.     dirPtr->isDisplayed = TRUE ;
  281.  
  282.     return( dirPtr->shellW ) ;
  283. }
  284.  
  285.  
  286. /*
  287.  *----------------------------------------------------------------------
  288.  *
  289.  * BuildSetData --
  290.  *
  291.  *    Given a pointer to a DirTree struct, use its files and
  292.  *    stat info to build and initialize the XtSetDataStruct
  293.  *    array used by the Set widget.
  294.  *
  295.  * Results:
  296.  *    A pointer to the newly created array of XtSetDataStruct *.
  297.  *
  298.  * Side effects:
  299.  *    Space is allocated, strings are copied into new space,
  300.  *    the entries of the XtSetDataStruct array are initialized.
  301.  *
  302.  *  Arguments:
  303.  *    dirPtr - Pointer to the dir struct to do this for.
  304.  *
  305.  *----------------------------------------------------------------------
  306.  */
  307.  
  308. static XtSetDataStruct **
  309. BuildSetData( DirTree *dirPtr )
  310. {
  311.     char    errLine[ ERRLINE_LEN ] ;
  312.     char    *pLocName = "BuildSetData()" ;
  313.  
  314.     int            i ;
  315.     XtSetDataStruct    **setPtr ;
  316.     char        s[ BUFSIZ ] ;
  317.  
  318.  
  319. #ifdef DEBUG
  320.     fprintf( pErrFp, "\n%s: in <%s>\n",
  321.     pLocName, dirPtr->name );
  322. #endif
  323.  
  324.     /* First make sure there are some files to do this for...
  325.     *  This could be kind of weird.
  326.     */
  327.  
  328.     if ( dirPtr->fileCnt == 0 )
  329.     return ( NULL ) ;
  330.  
  331.     /* Make the basic array of XtSetDataStruct pointers. */
  332.  
  333.     if ( ( setPtr = (XtSetDataStruct **)
  334.         calloc ( dirPtr->fileCnt, sizeof (XtSetDataStruct *)) ) == NULL )
  335.     FatalError( pLocName, "Out of Memory (calloc)" ) ;
  336.  
  337.     /* For each filename, build the XtSetDataStruct and make the
  338.     *  string to be displayed... for now assume that the -F stuff
  339.     *  is desired...
  340.     */
  341.  
  342.     for ( i = 0 ; i < dirPtr->fileCnt ; ++i )
  343.     {
  344.     XtSetDataStruct    *aPtr ;
  345.  
  346.     if ( ( aPtr = (XtSetDataStruct *)
  347.         malloc (sizeof (XtSetDataStruct)) ) == NULL )
  348.         FatalError( pLocName, "out of memory" ) ;
  349.  
  350.     strcpy ( s, dirPtr->files[ i ].file ) ;
  351.     if ( (dirPtr->files[ i ].statMode & S_GFMT) == S_GFDIR )
  352.         strcat ( s, "/" ) ;
  353.     else if ( (dirPtr->files[ i ].statMode & S_GFMT) == S_GFLNK)
  354.         strcat ( s, "@" ) ;
  355.     else if ( (dirPtr->files[ i ].statMode & S_GFMT) == S_GFSOCK)
  356.         strcat ( s, "=" ) ;
  357.     else if ( dirPtr->files[ i ].statMode & S_IXUSR
  358.         || dirPtr->files[ i ].statMode & S_IXGRP
  359.         || dirPtr->files[ i ].statMode & S_IXOTH )
  360.         strcat ( s, "*" ) ;
  361.  
  362.     aPtr->string = StrSave( s ) ;
  363.     aPtr->is_lit = FALSE ;
  364.  
  365.     setPtr[ i ] = aPtr ;
  366.  
  367. #ifdef DEBUG
  368.     fprintf ( pErrFp, "\t\t%d: <%s>, is_lit=%d\n",
  369.         i, setPtr[i]->string, setPtr[i]->is_lit ) ;
  370. #endif
  371.  
  372.     }
  373.  
  374.     return ( setPtr ) ;
  375. }
  376.  
  377.  
  378. /*
  379.  *----------------------------------------------------------------------
  380.  *
  381.  * ConfirmButtonPushed --
  382.  *
  383.  *    Callback for pressing the Confirm button on the
  384.  *    filename popup.
  385.  *
  386.  * Results:
  387.  *    None.
  388.  *
  389.  * Side effects:
  390.  *    Opens a window for the input pathname, if possible.
  391.  *
  392.  *  Arguments:
  393.  *    w - The calling widget's id.
  394.  *    client_data - Null, since no data passed to callback list.
  395.  *    call_data - Undefined by the Command widget.
  396.  *
  397.  *----------------------------------------------------------------------
  398.  */
  399.  
  400. static void
  401. ConfirmButtonPushed( Widget w, caddr_t client_data, caddr_t call_data )
  402. {
  403.     char    errLine[ ERRLINE_LEN ] ;
  404.     char    *pLocName = "PopupConfirm()" ;
  405.  
  406.     char    *fileNamePtr ;
  407.     DirTree    *dtPtr ;
  408.  
  409.  
  410. #ifdef DEBUG
  411.     fprintf ( pErrFp, "\n%s:\n", pLocName ) ;
  412. #endif
  413.  
  414.     /* Get the contents of the filename string. */
  415.  
  416.     if ( ( fileNamePtr
  417.     = XtDialogGetValueString ( dialogBox.dialogW ))
  418.         == NULL )
  419.         InternalError ( pLocName,
  420.             "Null string from XtDialogGetValueString" ) ;
  421.  
  422. #ifdef DEBUG
  423.     fprintf ( pErrFp, "\t<%s>\n", fileNamePtr ) ;
  424. #endif
  425.  
  426.     /* Have the directory tree expand as necessary. */
  427.  
  428.     if ( ( dtPtr = DirTree_Find ( fileNamePtr ) ) == NULL )
  429.     return ;
  430.  
  431.     /* Arrange for this directory to be displayed. */
  432.  
  433.     if ( ! dtPtr->isDisplayed )
  434.     BuildDirBox ( dtPtr ) ;
  435. }
  436.  
  437.  
  438. /*
  439.  *----------------------------------------------------------------------
  440.  *
  441.  * DoneButtonPushed --
  442.  *
  443.  *    The callback for the Done button.  The stored-up
  444.  *    selections are all output, and the program terminates.
  445.  *
  446.  * Results:
  447.  *    None.
  448.  *
  449.  * Side effects:
  450.  *    Output is done to the stdio, all X resources
  451.  *    are released, the program exits.
  452.  *
  453.  *  Arguments:
  454.  *    w - The calling widget's id.
  455.  *    client_data - Null, since no data passed to callback list.
  456.  *    call_data - Undefined by the Command widget.
  457.  *
  458.  *----------------------------------------------------------------------
  459.  */
  460.  
  461. static void
  462. DoneButtonPushed( Widget w, caddr_t client_data, caddr_t call_data )
  463. {
  464.     char    errLine[ ERRLINE_LEN ] ;
  465.     char    *pLocName = "DoneButtonPushed()" ;
  466.  
  467.  
  468. #ifdef DEBUG
  469.     fprintf( pErrFp, "\n%s:\n", pLocName );
  470. #endif
  471.  
  472.     /* Have the names dumped to the stdout. */
  473.  
  474.     DirTree_TreeTrav ( dirRootPtr, PostOrder, OutputFileNames, NULL ) ;
  475.  
  476.     /* We're done, close up shop. */
  477.  
  478.     XtDestroyApplicationContext ( appContext ) ;
  479.     exit ( 0 ) ;
  480. }
  481.  
  482.  
  483. /*
  484.  *----------------------------------------------------------------------
  485.  *
  486.  * EnterFileName --
  487.  *
  488.  *    Called when the "Enter File Name" button is pushed on
  489.  *    the dirbox.  Pops up the dialog widget.  This is the
  490.  *    only place where the dialog widget is manipulated.
  491.  *
  492.  * Results:
  493.  *    None.
  494.  *
  495.  * Side effects:
  496.  *    The dialog widget is constructed and popped up.
  497.  *
  498.  *  Arguments:
  499.  *    w - The calling widget's id.
  500.  *    client_data - Null, since no data passed to callback list.
  501.  *    call_data - Undefined by the Command widget.
  502.  *
  503.  *----------------------------------------------------------------------
  504.  */
  505.  
  506. static void
  507. EnterFileName( Widget w, caddr_t client_data, caddr_t call_data )
  508. {
  509.     char    errLine[ ERRLINE_LEN ] ;
  510.     char    *pLocName = "EnterFileName()" ;
  511.  
  512.     static int    boxBuilt = FALSE ;
  513.  
  514.  
  515. #ifdef DEBUG
  516.     fprintf ( pErrFp, "\n%s:\n", pLocName ) ;
  517. #endif
  518.  
  519.     if ( ! boxBuilt )
  520.     {
  521.     boxBuilt = TRUE ;
  522.     BuildDialogBox() ;
  523.     XtPopup ( dialogBox.shellW, XtGrabNone ) ;
  524.     }
  525. }
  526.  
  527.  
  528. /*
  529.  *----------------------------------------------------------------------
  530.  *
  531.  * OpenDirDown --
  532.  *
  533.  *    A button has been pushed that is to be interpreted
  534.  *    as a request to open the selected item as a directory.
  535.  *    This routine makes an honest effort to do so.
  536.  *
  537.  * Results:
  538.  *    None.
  539.  *
  540.  * Side effects:
  541.  *    With any luck a popup is made to display the directory.
  542.  *
  543.  * Arguments:
  544.  *    w - The calling widget's id.
  545.  *    client_data - Null, since no data passed to callback list.
  546.  *    call_data - XtSetReturnStruct *.
  547.  *
  548.  *----------------------------------------------------------------------
  549.  */
  550.  
  551. static void
  552. OpenDirDown( Widget w, caddr_t client_data, caddr_t call_data )
  553. {
  554.     char    errLine[ ERRLINE_LEN ] ;
  555.     char    *pLocName = "OpenDirDown()" ;
  556.  
  557.     DirTree    *dtPtr, *newDirPtr ;
  558.     char    path[ MAXPATHLEN ] ;
  559.     int        branchIdx ;
  560.  
  561.     XtSetReturnStruct    *retPtr = (XtSetReturnStruct *) call_data ;
  562.  
  563.  
  564.     /* First find the DirTree struct this happened in. */
  565.  
  566.     if ( ( dtPtr = DirTree_FindWidget ( dirRootPtr, SetW, w )) == NULL )
  567.     InternalError ( pLocName, "Searching for the Set widget" ) ;
  568.  
  569. #ifdef DEBUG
  570.     fprintf ( pErrFp, "\n%s:\n", pLocName ) ;
  571.     fprintf ( pErrFp, "\tstring=<%s>, index=%d\n",
  572.     retPtr->string, retPtr->index ) ;
  573. #endif
  574.  
  575.     /* If it's not a subdirectory, just do nothing. */
  576.  
  577.     if ( ( newDirPtr = DirTree_AddBranch( dtPtr, retPtr->index )) == NULL )
  578.     return ;
  579.  
  580.     /* If there's a relative path name for the directory we're
  581.     *  going down from, then construct one for the directory we're
  582.     *  going down to.  This keeps all 'local' references local, and
  583.     *  will be used to generate the names at 'done' time.
  584.     */
  585.  
  586. #ifdef DEBUG
  587.     fprintf ( pErrFp, "\trelName=0x%x\n", dtPtr->relName ) ;
  588. #endif
  589.  
  590.     if ( dtPtr->relName != NULL )
  591.     {
  592.     char    path[ MAXPATHLEN + 1 ] ;
  593.  
  594.     strcpy ( path, dtPtr->relName ) ;
  595.     strcat ( path, dtPtr->files[ retPtr->index ].file ) ;
  596.     strcat ( path, "/" ) ;
  597.     if ( newDirPtr->relName == NULL
  598.         || ( newDirPtr->relName != NULL
  599.         && strlen ( path ) < strlen ( newDirPtr->relName ) ) )
  600.             newDirPtr->relName = StrSave( path ) ;
  601.     }
  602.  
  603.     /* If it isn't being displayed already, then make
  604.     *  it show up.
  605.     */
  606.  
  607.     if ( ! newDirPtr->isDisplayed ) BuildDirBox ( newDirPtr ) ;
  608. }
  609.  
  610.  
  611. /*
  612.  *----------------------------------------------------------------------
  613.  *
  614.  * OutputFileNames --
  615.  *
  616.  *    Client routine of DirTree_TreeTrav(), this routine takes
  617.  *    a DirTree struct and outputs the names of the selected files
  618.  *    to stdout, with format depending on the availability of relName.
  619.  *
  620.  * Results:
  621.  *    None.
  622.  *
  623.  * Side effects:
  624.  *    Output to stdio.
  625.  *
  626.  *  Arguments:
  627.  *    dirTreePtr - DirTree struct to dump the contents of.
  628.  *    clientData - Anonymous data which will be ignored.
  629.  *
  630.  *----------------------------------------------------------------------
  631.  */
  632.  
  633. static void
  634. OutputFileNames( DirTree *dirTreePtr, void *clientData )
  635. {
  636.     char    errLine[ ERRLINE_LEN ] ;
  637.     char    *pLocName = "OutputFileNames()" ;
  638.  
  639.     XtSetDataStruct    **setPtr = dirTreePtr->setPtr ;
  640.  
  641.     int        i ;
  642.  
  643.  
  644. #ifdef DEBUG
  645.     fprintf ( pErrFp, "\n%s: <%s>\n",
  646.     pLocName, dirTreePtr->fullName ) ;
  647. #endif
  648.  
  649.     /* Don't bother messing around if there is nothing here. */
  650.  
  651.     if ( ! dirTreePtr->isDisplayed ) return ;
  652.  
  653. #ifdef DEBUG
  654.     fprintf ( pErrFp, "\tIs displayed\n" ) ;
  655. #endif
  656.  
  657.     for ( i = 0 ; i < dirTreePtr->fileCnt ; ++i )
  658.     {
  659.     char    path [ MAXPATHLEN + 1 ] ;
  660.  
  661.     if ( setPtr[i]->is_lit )
  662.     {
  663.  
  664. #ifdef DEBUG
  665.         fprintf ( pErrFp, "\t%d: set=<%s>, files=<%s>\n",
  666.         i,
  667.         setPtr[i]->string,
  668.         dirTreePtr->files[i].file ) ;
  669. #endif
  670.  
  671.         if ( dirTreePtr->relName != NULL )
  672.         strcpy ( path, dirTreePtr->relName ) ;
  673.         else
  674.         strcpy ( path, dirTreePtr->fullName ) ;
  675.     
  676.         strcat ( path, dirTreePtr->files[i].file ) ;
  677.         strcat ( path, " " ) ;
  678.         printf ( path ) ;
  679.     }
  680.     }
  681. }
  682.  
  683.  
  684. /*
  685.  *----------------------------------------------------------------------
  686.  *
  687.  * QuitButtonPushed --
  688.  *
  689.  *    The callback for pushing the Quit button.
  690.  *
  691.  * Results:
  692.  *    None.
  693.  *
  694.  * Side effects:
  695.  *    Blows out of the application abruptly.
  696.  *
  697.  *  Arguments:
  698.  *    w - The calling widget's id.
  699.  *    client_data - Null, since no data passed to callback list.
  700.  *    call_data - Undefined by the Command widget.
  701.  *
  702.  *----------------------------------------------------------------------
  703.  */
  704.  
  705. static void
  706. QuitButtonPushed( Widget w, caddr_t client_data, caddr_t call_data )
  707. {
  708.     char    errLine[ ERRLINE_LEN ] ;
  709.     char    *pLocName = "QuitButtonPushed()" ;
  710.  
  711.  
  712. #ifdef DEBUG
  713.     fprintf( pErrFp, "\n%s:\n", pLocName );
  714. #endif
  715.  
  716.     XtDestroyApplicationContext ( appContext ) ;
  717.     exit ( 1 ) ;
  718. }
  719.  
  720.  
  721. /*
  722.  *----------------------------------------------------------------------
  723.  *
  724.  * UpButtonPushed --
  725.  *
  726.  *    The callback for pressing the Up button.  A dir box
  727.  *    is opened on the ancestor of the directory in which
  728.  *    the button was pushed.
  729.  *
  730.  * Results:
  731.  *    None.
  732.  *
  733.  * Side effects:
  734.  *    If everthing goes well, the relative name of the
  735.  *    ancestor may be updated, and a dir box is constructed
  736.  *    and displayed.
  737.  *
  738.  *  Arguments:
  739.  *    w - The calling widget's id.
  740.  *    client_data - Null, since no data passed to callback list.
  741.  *    call_data - Undefined by the Command widget.
  742.  *
  743.  *----------------------------------------------------------------------
  744.  */
  745.  
  746. static void
  747. UpButtonPushed( Widget w, caddr_t client_data, caddr_t call_data )
  748. {
  749.     char    errLine[ ERRLINE_LEN ] ;
  750.     char    *pLocName = "UpButtonPushed()" ;
  751.  
  752.     DirTree    *dtPtr ;
  753.  
  754. #ifdef DEBUG
  755.     fprintf( pErrFp, "\n%s:\n", pLocName );
  756. #endif
  757.  
  758.     /* First find the DirTree struct this happened in. */
  759.  
  760.     if ( ( dtPtr = DirTree_FindWidget ( dirRootPtr, UpW, w )) == NULL )
  761.     InternalError ( pLocName, "Searching for the Up widget" ) ;
  762.  
  763.     /* Don't bother hanging out if this is the top of the tree...
  764.     *  can't go up from here.
  765.     */
  766.  
  767.     if ( dtPtr->rootPtr == NULL ) return ;
  768.  
  769.     /* If there's a relative path name for the directory we're
  770.     *  going up from, then construct one for the directory we're
  771.     *  going up to.  This keeps all 'local' references local, and
  772.     *  will be used to generate the names at 'done' time.
  773.     */
  774.  
  775. #ifdef DEBUG
  776.     fprintf ( pErrFp, "\trelName=0x%x\n", dtPtr->relName ) ;
  777. #endif
  778.  
  779.     if ( dtPtr->relName != NULL )
  780.     {
  781.     char    path[ MAXPATHLEN + 1 ] ;
  782.  
  783.     strcpy ( path, dtPtr->relName ) ;
  784.     strcat ( path, "../" ) ;
  785.     if ( dtPtr->rootPtr->relName == NULL
  786.         || ( dtPtr->rootPtr->relName != NULL
  787.         && strlen ( path ) < strlen ( dtPtr->rootPtr->relName ) ) )
  788.             dtPtr->rootPtr->relName = StrSave( path ) ;
  789.     }
  790.  
  791.     /* Build and display a box for the root of this directory,
  792.     *  if it hasn't been done already.
  793.     */
  794.  
  795.     if ( ! dtPtr->rootPtr->isDisplayed )
  796.     BuildDirBox ( dtPtr->rootPtr ) ;
  797. }
  798.  
  799.  
  800.