home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / edit / point20 / getinput.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-04  |  19.8 KB  |  763 lines

  1. #include "pt.h"
  2. #include "string.h"
  3. #include "direct.h"
  4. #include "conio.h"
  5.  
  6. static unsigned char buffer[101];
  7. static int nameRow, nameCol;
  8. static int buttonState;
  9. static int space;
  10. static int maxNameSize;
  11.  
  12. unsigned char * pascal
  13. /* XTAG:getFileName */
  14. getFileName(prompt)
  15.     unsigned char *prompt;
  16. {
  17.     extern union REGS rin, rout;
  18.     extern unsigned char filePattern[];
  19.     extern unsigned char msgBuffer[];
  20.     extern unsigned char textBuffer[];
  21.     extern unsigned char fsPatterns[];
  22.     extern unsigned char fsDirs[];
  23.     extern unsigned char scratchFileName[];
  24.     extern int scrRows, scrCols;
  25.     extern unsigned char bannerColor;
  26.     extern unsigned char textColor, selColor;
  27.     extern unsigned char scrMapReset;
  28.     extern int debug;
  29.     extern int fsMenu;
  30.     extern int fileSort;
  31.     extern unsigned int dispMemory;
  32.     extern struct SREGS segRegs;
  33.     extern struct menuBlock far *menus[];
  34.     extern unsigned char startDirectory[];
  35.     extern unsigned char startDrive;
  36.     extern int helpMode;
  37.     extern unsigned char currentDirectory[];
  38.     extern unsigned char currentDrive;
  39.     extern int addHandle;
  40.     
  41.     unsigned char *fileName = NULL, *p, *q, *fileMarks;
  42.     unsigned char extension[3];
  43.     unsigned char far *fp;
  44.     unsigned int *ip;
  45.     int i, k, n, row, col, ret, iBuffer, fileCount;
  46.     int firstName, lastName;
  47.     int maxFiles, extensionLength;
  48.     int maxCol, offset;
  49.     int saveRow, saveCol;
  50.     int gettingDirectories;
  51.     int saveHelpMode;
  52.     struct SREGS sr;
  53.     int selectedRow, selectedCol;
  54.  
  55.     /* use the current directory that the user set last */
  56.     setDefaultDrive(currentDrive);
  57.     chdir(currentDirectory);
  58.  
  59.     /* set up so we know when to allocate space again */
  60.     space = 0;
  61.     saveHelpMode = helpMode;
  62.     helpMode = 0;
  63.     
  64. restart:
  65.     msg("***** Please wait while directory is read *****", 1);
  66.     
  67.     maxNameSize = 1;
  68.     maxFiles = 512;
  69.  
  70.     while( 1 ) {
  71.         /* get some space to put the names in */
  72.         if( space == 0 ) {
  73.             rin.h.ah = 0x48;
  74.             rin.x.bx = 4 * maxFiles;  /* 16-byte paragraphs */
  75.             intdos(&rin, &rout);
  76.             n = rout.x.cflag;
  77.             if( n & 0x1 ) {
  78.                 maxFiles >>= 1;    /* divide by 2 */
  79.                 if( maxFiles > 8 )
  80.                     continue;
  81.                 msg("No space to sort file names", 3);
  82.                 fileName = NULL;
  83.                 space = 0;
  84.                 goto askName;
  85.             }
  86.             space = rout.x.ax;
  87.         }
  88.         break;
  89.     }
  90.  
  91.     /* find the names */
  92.     fileCount = 0;
  93.  
  94.     /* first get all the directories */
  95.     gettingDirectories = 1;
  96.     fileName = findFirstPatternFile( "*.*", 0x10, buffer );
  97.  
  98.     while( fileCount < maxFiles ) {
  99.  
  100.         if( fileName == NULL ) {
  101. /* for some reason I can't figure out.  The directory search fails when */
  102. /* I remove this statement.  So I left it in. */
  103. if( debug==91 ) { setCPos(23,0);cprintf(" %d ", fileCount); }
  104.             /* are we done or just done with the directories? */
  105.             if( gettingDirectories ) {
  106.                 gettingDirectories = 0;
  107.                 fileName = findFirstPatternFile( filePattern,
  108.                             0x1, buffer );
  109.                 continue;
  110.             } else
  111.                 break;
  112.         }
  113.  
  114.         /* put in the string that defines the sort order (1st char) */
  115.         /* and marked the file type (2nd char) */
  116.         if( gettingDirectories ) {
  117.             if( (buffer[21]&0x10) != 0 )    /* a directory */
  118.                 /* directories will sort to the beginning */
  119.                 fileMarks = "DD";
  120.             else
  121.                 /* get only directories this pass */
  122.                 goto getNextFileName;
  123.         } else {
  124.             if( (buffer[21]&0x3) != 0 )
  125.                 /* hidden or read-only files */
  126.                 fileMarks = "ZH";
  127.             else
  128.                 fileMarks = "ZN";
  129.         }
  130.  
  131.         /* move the name into the buffer */
  132.         offset = 64 * fileCount;
  133.         /* put in the char to make directories sort in front */
  134.         movedata(segRegs.ds, (int)fileMarks, space, offset++, 1);
  135.  
  136.         if( fileSort == 2 ) {
  137.             /* find the extension */
  138.             q = NULL;
  139.             p = &buffer[30];
  140.             while( *p != '\0' ) {
  141.                 if( *p == '.' )
  142.                     q = p;
  143.                 ++p;
  144.             }
  145.             /* found a '.' that was not a ".."? */
  146.             i = 0;
  147.             if( q != NULL && buffer[30] != '.' ) {
  148.                 /* remove the extension from the name by */
  149.                 /* overlaying the '.' with end-of-string */
  150.                 *q++ = '\0';
  151.                 /* get the extension */
  152.                 while( *q != '\0' )
  153.                     extension[i++] = *q++;
  154.             }
  155.             /* pad extension with blanks */
  156.             extensionLength = i;
  157.             while( i < 3 )
  158.                 extension[i++] = ' ';
  159.             movedata(segRegs.ds, (int)(&extension[0]), space,
  160.                 offset, 3);
  161.             offset += 3;
  162.         }
  163.  
  164.         n = strlen(fileName) + 1;    /* + 1 for the '\0' */
  165.         if( fileSort == 2 && extensionLength > 0 ) {
  166.             n -= (extensionLength + 1);
  167.             /* +1 for the "." */
  168.             /* erase the extension from fileName */
  169.             fileName[n - 1] = '\0';
  170.         }
  171.         /* put in the file type chararacter */
  172.         fileName[n] = *(fileMarks + 1);
  173.         movedata( segRegs.ds, (int)fileName, space, offset, n+1 );
  174.         k = n + 1;    /* extra +1 for spacing on screen */
  175.         if( k > maxNameSize )
  176.             maxNameSize = k;
  177.         ++fileCount;
  178.  
  179. getNextFileName:
  180.         /* find the next matching file name */
  181.         fileName = findNextPatternFile(buffer);
  182.     }
  183.  
  184.     /* adjust for the size of the extension if sorting by extension */
  185.     if( fileSort == 2 )
  186.         maxNameSize += 4;
  187.     /* sort the names */
  188. if( fileSort != 0 ) {
  189.     for(k = 1; k < fileCount; k++) {
  190.         movedata(space, 64*k, segRegs.ds, (int)(&msgBuffer[0]),
  191.             maxNameSize);
  192.         i = k-1;
  193.         while( i >= 0 ) {
  194.             movedata(space, 64*i, segRegs.ds,
  195.                 (int)(&textBuffer[0]), maxNameSize);
  196.             if( strcmp(textBuffer, msgBuffer) <= 0 )
  197.                 break;
  198.             movedata(segRegs.ds, (int)(&textBuffer[0]),
  199.                 space, 64*(i+1), maxNameSize);
  200.             i--;
  201.         }
  202.         movedata(segRegs.ds, (int)(&msgBuffer[0]), space, 64*(i+1),
  203.             maxNameSize);
  204.     }
  205. }
  206.  
  207.     firstName = 0;
  208.     selectedRow = 0;
  209.     selectedCol = 0;
  210. doPaging:
  211.     /* clear the screen buffer where the names will go */
  212.     setMap(0, 0, scrRows-2, scrCols-1, 2, textColor);
  213.  
  214.     /* fill in the names */
  215.     n = firstName;
  216.  
  217.     /* maxNameSize has two blanks included in it so adjust for that */
  218.     maxCol = scrCols - (maxNameSize - 2);
  219.     for(col = 0; col < maxCol; col += maxNameSize) {
  220.         for(row = 2; row < scrRows-1; row++) {
  221.             if( n >= fileCount ) {
  222.                 lastName = fileCount;
  223.                 goto displayNames;
  224.             }
  225.             movedata(space, 64*n, segRegs.ds,
  226.                 (int)(&textBuffer[0]), 64);
  227.  
  228.             k = 0;    /* k counts screen character positions */
  229.             if( textBuffer[0] == 'D' )
  230.                 ret = selColor;    /* directory */
  231.             else
  232.                 ret = textColor;    /* ordinary file */
  233.  
  234.             /* is this filename selected? */
  235.             if( row == selectedRow && col == selectedCol )
  236.                 ret = selColor;        /* selected */
  237.             else
  238.                 ret = textColor;    /* not selected */
  239.  
  240.             i = (fileSort==2) ? 4 : 1;
  241.             for(  ; textBuffer[i] != '\0'; ++i)
  242.                 displayChar(row, col+k++,
  243.                     tolower(textBuffer[i]), ret);
  244.             iBuffer = i + 1;
  245.             if( fileSort == 2 && textBuffer[1] != ' ' ) {
  246.                 displayChar(row, col+k++, '.', ret);
  247.                 for(i = 1; i<4 && textBuffer[i]!=' '; i++)
  248.                     displayChar(row, col+k++,
  249.                         tolower(textBuffer[i]), ret);
  250.             }
  251.             if( textBuffer[iBuffer] == 'D' )
  252.                 displayChar(row, col+k, '\\', ret);
  253.             else if( textBuffer[iBuffer] == 'H' )
  254.                 displayChar(row, col+k, '*', ret);
  255.             ++n;
  256.         }
  257.     }
  258.     lastName = n;
  259.  
  260. displayNames:
  261.     /* remember these so that we can detect invalid click locations */
  262.     saveRow = row;
  263.     saveCol = col;
  264.     (void)getcwd(&msgBuffer[0], MSGBUFFERSIZE);
  265.     sprintf(textBuffer, "%d files in %s matching %s%s",
  266.         fileCount, msgBuffer, filePattern,
  267.         (fileCount < maxFiles ? "" : "SOME FILE NAMES MISSING")
  268.         );
  269.     col = 0;
  270.     for(i = 0; textBuffer[i] != '\0' && col < scrCols; i++)
  271.         displayChar(1, col++, textBuffer[i], bannerColor);
  272.     while( col < scrCols )
  273.         displayChar(1, col++, ' ', bannerColor);
  274.     pulldown(fsMenu);
  275.     updateScreen(0, scrRows-2);
  276.     fileName = getInput(prompt, "", 2);
  277.  
  278.     if( fileName != NULL )    /* A string was entered (no mouse button) */
  279.         goto processFilename;
  280.  
  281.     /* otherwise we got a mouse click and row and col are set */
  282.     /* normalize to first char in field */
  283.     if( nameRow > 0 ) {
  284.         /* normalize to first character in field */
  285.         nameCol = maxNameSize*(nameCol/maxNameSize);
  286.  
  287.         /* see if the click is where we put a file name */
  288.         if( (nameCol > saveCol) || (nameRow == scrRows-1)
  289.          || ((nameCol == saveCol) && (nameRow > saveRow)) ) {
  290.              /* if not, CD to the parent directory */
  291.              strcpy(scratchFileName, "..");
  292.             goto changeDirectory;
  293.         }
  294.  
  295. #ifdef XXXXXX
  296. FOR NOW WE WILL ONLY REQUIRE A SINGLE CLICK
  297.  
  298.         /* We require a double click on the name. */
  299.         /* The first selects the filename and the second */
  300.         /* picks the filename for loading into the window */
  301.         if( nameRow != selectedRow || nameCol != selectedCol ) {
  302.             selectedRow = nameRow;
  303.             selectedCol = nameCol;
  304.             goto doPaging;
  305.         }
  306. #endif
  307.  
  308.         /* now pick up the filename from the screen buffer */
  309.         iBuffer = 0;    /* next char in buffer */
  310.         ip = (unsigned int *)&fp;
  311.         *ip++ = (scrCols<<1)*nameRow + 2*nameCol;
  312.         *ip = dispMemory;
  313.         if( *fp == ' ' )    /* don't allow empty filenames */
  314.             goto doPaging;
  315.         while( *fp != ' ' ) {
  316.             scratchFileName[iBuffer++] = *fp;
  317.             fp += 2;
  318.         }
  319.  
  320.         /* if it ends with a '\' it is a directory name */
  321.         /* so change to that directory */
  322.         if( scratchFileName[iBuffer-1] == '\\' ) {
  323.             scratchFileName[iBuffer-1] = '\0';
  324.         changeDirectory:
  325.             chdir(scratchFileName);
  326.             goto restart;
  327.         }
  328.         else if( scratchFileName[iBuffer-1] == '*' )
  329.             /* eliminate the read-only flag '*' */
  330.             scratchFileName[iBuffer-1] = '\0';
  331.         else
  332.             scratchFileName[iBuffer] = '\0';
  333.  
  334.         /* create the full path name, unless it already is one */
  335.         if( scratchFileName[0] != '\\'
  336.          && scratchFileName[1] != ':'
  337.          && scratchFileName[2] != '\\'
  338.         ) {
  339.             /* prepend the pathname of the current directory */
  340.             (void)getcwd(textBuffer, MSGBUFFERSIZE);
  341.             n = strlen(textBuffer) - 1;
  342.             if( textBuffer[n] != '\\' )
  343.                 strcat(textBuffer, "\\");
  344.             strncat(textBuffer, scratchFileName, FILENAMESIZE);
  345.             /* copy it back into scratchFileName where it will */
  346.             /* not be changed by other editor activity */
  347.             strcpy(scratchFileName, textBuffer);
  348.         }
  349.         if( iBuffer != 0 )
  350.             fileName = &scratchFileName[0];
  351.     } else if( 0 == nameRow ) {    /* menu selection */
  352.         /* figure out which item on the menu */
  353.         n = menus[fsMenu]->nItems;
  354.         col = 0;
  355.         for(i = 1; i < n-1; i++) {
  356.             col += farStrlen(menus[fsMenu]->cmdName[i]);
  357.             if( col > nameCol )
  358.                 break;
  359.         }
  360.         n = menus[fsMenu]->cmdNumber[i];
  361. GotNewN:
  362.         switch( n ) {
  363.  
  364.         default:
  365.             goto doPaging;
  366.  
  367.         /* change directory and/or drive */
  368.         case 1: case 2: case 3: case 4: case 5:
  369.         case 6: case 7: case 8: case 9: case 10:
  370.         case 11: case 12: case 13: case 14: case 15:
  371.         case 16: case 17: case 18: case 19: case 20:
  372.             CopyNthPattern(n-1, fsDirs, &textBuffer[0]);
  373.             if( textBuffer[1] == ':' ) {
  374.                 setDefaultDrive(toupper(textBuffer[0])-'A');
  375.                 k = 2;
  376.             } else
  377.                 k = 0;
  378.             if( textBuffer[k] != '\0' )
  379.                 chdir(&textBuffer[k]);
  380.             goto restart;
  381.  
  382.  
  383.         /* change filePattern to a set file pattern */
  384.         case 21: case 22: case 23: case 24: case 25:
  385.         case 26: case 27: case 28: case 29: case 30:
  386.         case 31: case 32: case 33: case 34: case 35:
  387.         case 36: case 37: case 38: case 39: case 40:
  388.             CopyNthPattern(n-21, &fsPatterns[0], &filePattern[0]);
  389.             goto restart;
  390.  
  391.         /* drop down a menu */
  392.         case 41: case 42: case 43: case 44: case 45:
  393.         case 46: case 47: case 48: case 49: case 50:
  394.         case 51: case 52: case 53: case 54: case 55:
  395.         case 56: case 57: case 58: case 59: case 60:
  396.             n = menu(menus[n-40], 1, nameCol);
  397.             goto GotNewN;
  398.  
  399.         /* change the file sorting */
  400.         case 61: case 62: case 63:
  401.             fileSort = n - 61;
  402.             goto restart;
  403.  
  404.         case 64:    /* next page */
  405.             if( lastName < fileCount )
  406.                 firstName = lastName;
  407.             else
  408.                 firstName = 0;
  409.             goto doPaging;
  410.  
  411.         case 65:    /* previous page */
  412.             n = (scrRows-4)*((scrCols+2)/maxNameSize);
  413.             firstName -= n;
  414.             if( firstName < 0 )
  415.                 firstName = 0;
  416.             goto doPaging;
  417.  
  418.         case 66:    /* new file pattern */
  419.             p = getInput("New file pattern: ", "*.*", 3);
  420.             if( p != NULL )
  421.                 strcpy(filePattern, p);
  422.             goto restart;
  423.  
  424.         case 67:    /* cancel load */
  425.             goto cancelLoad;
  426.  
  427.         case 68:    /* goto to Point startup directory */
  428.             setDefaultDrive(startDrive);
  429.             chdir(startDirectory);
  430.             goto restart;
  431.         case 69:    /* new drive or directory */
  432.             p = getInput("New drive and/or directory: ",
  433.                 "C:\\", 3);
  434.             if( p != NULL ) {
  435.                 if( p[1] == ':' ) {
  436.                     setDefaultDrive(toupper(p[0])-'A');
  437.                     k = 2;
  438.                 } else
  439.                     k = 0;
  440.                 if( p[k] != '\0' )
  441.                     chdir(&p[k]);
  442.             }
  443.             goto restart;
  444.  
  445.         }
  446.     } else
  447.         goto cancelLoad;
  448.  
  449. askName:
  450.     /* if we didn't get a name -- ask for one */
  451.     if( fileName == NULL )
  452.         fileName = getInput(prompt, "", 3);
  453.     /* do not process the filename since it is already a full pathname */
  454.     goto cancelLoad;
  455. processFilename:
  456.     /* capture the full pathname using the drive and directory */
  457.     /* before we change it back to the startup drive and directory */
  458.     fileName = makeFullPathname(fileName);
  459.  
  460. cancelLoad:
  461.     /* restore the screen */
  462.     redrawBox(0, 0, scrRows-1, scrCols-1);
  463.     updateScreen(0, scrRows-1);
  464.  
  465.     /* release the allocated space */
  466.     if( space != NULL ) {
  467.         rin.h.ah = 0x49;
  468.         segread(&sr);
  469.         sr.es = space;
  470.         intdosx(&rin, &rout, &sr);
  471.     }
  472.     helpMode = saveHelpMode;
  473.  
  474.     /* remember the user's current directory and drive */
  475.     (void)getcwd(¤tDirectory[0], FILENAMESIZE);
  476.     currentDrive = getDefaultDrive();
  477.  
  478.     /* and return to the startup drive and directory */
  479.     setDefaultDrive(startDrive);
  480.     chdir(startDirectory);
  481.  
  482.     return fileName;
  483. }
  484.  
  485.  
  486. void pascal
  487. /* XTAG:CopyNthPattern */
  488. CopyNthPattern(n, patterns, toString)
  489.     int n;
  490.     unsigned char far *patterns;
  491.     unsigned char *toString;
  492. /* patterns starts and ends with " */
  493. /* it contains 0 or more patterns separated with ";"s */
  494. /* skip "n" patterns (that is, skip "n" ";"s) and then */
  495. /* copy the next pattern into "toString" */
  496. {
  497.     register unsigned char ch;
  498.     register unsigned char *p;
  499.  
  500.     p = &patterns[1];    /* skip the initial " */
  501.     /* scan past n ";"s */
  502.     while( n-- > 0 ) {
  503.         /* find the next ";" */
  504.         while( 1 ) {
  505.             ch = *p++;
  506.             if( ch == ';' )
  507.                 break;
  508.             if( ch == '\0' ) {
  509.                 /* not enough patterns so */
  510.                 /* just use the first one */
  511.                 p = &patterns[1];    /* skip initial " */
  512.                 goto noMorePatterns;
  513.             }
  514.         }
  515.     }
  516. noMorePatterns:
  517.     while( 1 ) {
  518.         ch = *p++;
  519.         if( ch == ';' || ch == '\0' || ch == '"' )
  520.             break;
  521.         *toString++ = ch;
  522.     }
  523.     *toString = '\0';
  524. }
  525.  
  526.  
  527. #ifdef QUICKSORT
  528. /********************* QUICKSORT *************************************/
  529. #define splitter &textBuffer[0]
  530. #define item &textBuffer[64]
  531. #define temp &textBuffer[128]
  532.  
  533. void pascal
  534. /* XTAG:qsort */
  535. qsort(low, high)
  536.     int low, high;
  537. {
  538.     extern unsigned char msgBuffer[];
  539.     extern unsigned char textBuffer[];
  540.     extern struct SREGS segRegs;
  541.  
  542.     int mid, i, lastLow;
  543.  
  544.     /* if there are 1 or fewer items to sort, we are already done! */
  545.     if( low >= high )
  546.         return;
  547.  
  548.     /* pick the middle item and swap it with the first item */
  549.     mid = (high+low)/2; /* or mid = randint(low,high) */
  550.  
  551.     /* pick up the splitting item */
  552.     movedata(space, 64*mid, segRegs.ds, splitter, maxNameSize);
  553.  
  554.     /* copy the first element into the mid slot */
  555.     movedata(space, 64*low, temp, maxNameSize);
  556.     movedata(segRegs.ds, temp, space, 64*mid, maxNameSize);
  557.  
  558.     /* copy the splitting item into the low slot */
  559.     movedata(segRegs.ds, splitter, space, 64*low, maxNameSize);
  560.  
  561.     lastLow = low;
  562.     for(i = low+1; i <= high; i++) {
  563.         /* get the item in slot i */
  564.         movedata(space, 64*i, segRegs.ds, item, maxNameSize);
  565.         /* compare against the splitting element */
  566.         if( strcmp(item, splitter) < 0 ) {
  567.             /* if it is lower than the splitter, */
  568.             /* exchange it with ++lastLow */
  569.             ++lastLow;
  570.             movedata(space, 64*lastLow,
  571.                 segRegs.ds, temp, maxNameSize);
  572.             movedata(segRegs.ds, item, space, 64*lastLow,
  573.                 maxNameSize);
  574.             movedata(segRegs.ds, temp, space, 64*i, maxNameSize);
  575.         }
  576.     }
  577.     movedata(space, 64*lastLow, segRegs.ds, temp, maxNameSize);
  578.     movedata(segRegs.ds, temp, space, 64*low, maxNameSize);
  579.     movedata(segRegs.ds, splitter, space, 64*lastLow, maxNameSize);
  580.     
  581.     /* Reduce the stack growth by doing the shortest one first. */
  582.     /* This always keeps the longer intervals on the stack and */
  583.     /* there must necessarily be fewer intervals if they are longer. */
  584.     if( low < lastLow )
  585.         qsort(low, lastLow-1);
  586.     if( lastLow+1 < high )
  587.         qsort(lastLow+1, high);
  588. }
  589. /************************* END QUICKSORT *****************************/
  590. #endif
  591.  
  592. unsigned char * pascal
  593. /* XTAG:getInput */
  594. getInput(prompt, strDefault, oneChar)
  595.     unsigned char *prompt, *strDefault;
  596.     int oneChar;
  597. {
  598.     extern union REGS rin, rout;
  599.     extern struct window *selWindow;
  600.     extern long selBegin, selEnd;
  601.     extern int debug;
  602.     extern unsigned char msgColor, promptColor;
  603.     extern int scrRows, scrCols;
  604.     extern int evhead, evtail;
  605.     extern struct event events[];
  606.     extern int cursorMouse;
  607.     extern int menuLine;
  608.  
  609.     int i, j, fileId, col;
  610.     int pLen, firstTime, bottomRow;
  611.     int saveCursorMouse, fn;
  612.     long cp;
  613.     unsigned char ch, scan, *retValue;
  614.  
  615.     retValue = buffer;
  616.     pLen = strlen(prompt);
  617.     saveCursorMouse = cursorMouse;
  618.     cursorMouse = 1;
  619.  
  620.     firstTime = 1;
  621.     strncpy(buffer, strDefault, 100);
  622.     i = strlen(buffer);
  623.     bottomRow = scrRows - 1;
  624.     if( menuLine < 0 )
  625.         --bottomRow;
  626.     switch( oneChar ) {
  627.         /* this is the entry that does not erase the prompt */
  628.         case 5:
  629.             firstTime = 0;
  630.             oneChar = 0;
  631.             break;
  632.         /* these signify that getFileName called */
  633.         case 4:
  634.         case 3:
  635.             oneChar -= 3;
  636.         case 2:
  637.             if( menuLine < 0 )
  638.                 ++bottomRow;
  639.             break;
  640.     }
  641.     
  642.     /* each iteration picks up a keystroke or mouse click */
  643.     while( 1 ) {
  644.         /* redraw the prompt and input line so far */
  645.         setMap(bottomRow, 1, bottomRow, 78, 0, msgColor);
  646.         col = 1;
  647.         j = 0;
  648.         while( 1 ) {
  649.             ch = prompt[j++];
  650.             if( ch == '\0' || col > 78 )
  651.                 break;
  652.             displayChar(bottomRow, col++, ch, msgColor);
  653.         }
  654.         j = 0;
  655.         while( j < i ) {
  656.             ch = buffer[j++];
  657.             displayChar(bottomRow, col++, ch, promptColor);
  658.         }
  659.         updateScreen(bottomRow, scrRows-1);
  660.  
  661.         /* wait for a keystroke or mouse button */
  662.         while( 1) {
  663.             if( isKeystroke() != 0 ) {
  664.                 ch = getKeystroke(&scan);
  665.                 fn = translateKey(ch, scan);
  666.                 /* if cursor returns 1 then it was a cursor */
  667.                 /* movement character and so do not put it */
  668.                 /* in the string */
  669.                 if( cursor(fn, 0) )
  670.                     continue;
  671.                 break;
  672.             }
  673.             if( isMouseEvent(0) ) {    /* mouse event? */
  674.                 /* get the current mouse position */
  675.                 evhead = getMouseEvent();
  676.                 j = events[evhead].buttons;
  677.                 if( oneChar == 2 && j != 0 ) {
  678.                     retValue = NULL;
  679.                     /* return values to getFileName */
  680.                     nameRow = events[evhead].vertical>>3;
  681.                     nameCol =
  682.                         events[evhead].horizontal>>3;
  683.                     buttonState = j;
  684.                     goto ret;
  685.                 }
  686.                 if( oneChar == 1 && j != 0 ){
  687. #ifdef HARDCONFIRMS
  688.                     /* only confirm on bottom row */
  689.                     if( (events[evhead].vertical>>3)
  690.                                 < bottomRow )
  691.                         continue;
  692. #endif
  693.                     ch = (unsigned char)
  694.                         ((j == 1) ? 'y' : 'n');
  695.                     break;    /* since we got the one */
  696.                         /* character we need */
  697.                 } else if( j == 1 )
  698.                     goto newLine;
  699.                 else if( j == 2 ) { /* right mouse button */
  700.                     /* clear the default if there are */
  701.                     /* no other keystrokes */
  702.                     if( firstTime ) {
  703.                         firstTime = 0;
  704.                         i = 0;
  705.                     }
  706.                     /* copy selection into the string */
  707.                     cp = selBegin;
  708.                     fileId = selWindow->fileId;
  709.                     while( 1 ) {
  710.                         ch = readChar(fileId, cp++);
  711.                         if( cp > selEnd )
  712.                             break;
  713.                         buffer[i++] = ch;
  714.                         if( i >= 100 )
  715.                             --i;
  716.                     }
  717.                     break;
  718.                 }
  719.             }
  720.         }
  721.         switch( ch ) {
  722.  
  723.         case '\33':    /* ESCape */
  724.             retValue = NULL;
  725.             /* this signals getFileName that the load was */
  726.             /* cancelled */
  727.             nameRow = -1;
  728.             goto ret;
  729.  
  730.         case '\b':
  731.             if( i > 0 )
  732.                 --i;
  733.             break;
  734.  
  735.         case '\177':    /* ascii del -- control-backspace */
  736.             i = 0;
  737.             break;
  738.  
  739.         case '\r':
  740.         newLine:
  741.             buffer[i] = '\0';
  742.             goto ret;
  743.         
  744.         default:
  745.             if( firstTime )
  746.                 i = 0;
  747.             buffer[i++] = ch;
  748.             if( i >= 100 )
  749.                 --i;
  750.             if( oneChar == 1 )
  751.                 goto ret;
  752.             break;
  753.         }
  754.         firstTime = 0;
  755.     }
  756. ret:
  757.     if( bottomRow == (scrRows - 1) )
  758.         msg("", 1);
  759.     cursorMouse = saveCursorMouse;
  760.  
  761.     return retValue;
  762. }
  763.