home *** CD-ROM | disk | FTP | other *** search
- #include "pt.h"
- #include "string.h"
- #include "direct.h"
- #include "conio.h"
-
- static unsigned char buffer[101];
- static int nameRow, nameCol;
- static int buttonState;
- static int space;
- static int maxNameSize;
-
- unsigned char * pascal
- /* XTAG:getFileName */
- getFileName(prompt)
- unsigned char *prompt;
- {
- extern union REGS rin, rout;
- extern unsigned char filePattern[];
- extern unsigned char msgBuffer[];
- extern unsigned char textBuffer[];
- extern unsigned char fsPatterns[];
- extern unsigned char fsDirs[];
- extern unsigned char scratchFileName[];
- extern int scrRows, scrCols;
- extern unsigned char bannerColor;
- extern unsigned char textColor, selColor;
- extern unsigned char scrMapReset;
- extern int debug;
- extern int fsMenu;
- extern int fileSort;
- extern unsigned int dispMemory;
- extern struct SREGS segRegs;
- extern struct menuBlock far *menus[];
- extern unsigned char startDirectory[];
- extern unsigned char startDrive;
- extern int helpMode;
- extern unsigned char currentDirectory[];
- extern unsigned char currentDrive;
- extern int addHandle;
-
- unsigned char *fileName = NULL, *p, *q, *fileMarks;
- unsigned char extension[3];
- unsigned char far *fp;
- unsigned int *ip;
- int i, k, n, row, col, ret, iBuffer, fileCount;
- int firstName, lastName;
- int maxFiles, extensionLength;
- int maxCol, offset;
- int saveRow, saveCol;
- int gettingDirectories;
- int saveHelpMode;
- struct SREGS sr;
- int selectedRow, selectedCol;
-
- /* use the current directory that the user set last */
- setDefaultDrive(currentDrive);
- chdir(currentDirectory);
-
- /* set up so we know when to allocate space again */
- space = 0;
- saveHelpMode = helpMode;
- helpMode = 0;
-
- restart:
- msg("***** Please wait while directory is read *****", 1);
-
- maxNameSize = 1;
- maxFiles = 512;
-
- while( 1 ) {
- /* get some space to put the names in */
- if( space == 0 ) {
- rin.h.ah = 0x48;
- rin.x.bx = 4 * maxFiles; /* 16-byte paragraphs */
- intdos(&rin, &rout);
- n = rout.x.cflag;
- if( n & 0x1 ) {
- maxFiles >>= 1; /* divide by 2 */
- if( maxFiles > 8 )
- continue;
- msg("No space to sort file names", 3);
- fileName = NULL;
- space = 0;
- goto askName;
- }
- space = rout.x.ax;
- }
- break;
- }
-
- /* find the names */
- fileCount = 0;
-
- /* first get all the directories */
- gettingDirectories = 1;
- fileName = findFirstPatternFile( "*.*", 0x10, buffer );
-
- while( fileCount < maxFiles ) {
-
- if( fileName == NULL ) {
- /* for some reason I can't figure out. The directory search fails when */
- /* I remove this statement. So I left it in. */
- if( debug==91 ) { setCPos(23,0);cprintf(" %d ", fileCount); }
- /* are we done or just done with the directories? */
- if( gettingDirectories ) {
- gettingDirectories = 0;
- fileName = findFirstPatternFile( filePattern,
- 0x1, buffer );
- continue;
- } else
- break;
- }
-
- /* put in the string that defines the sort order (1st char) */
- /* and marked the file type (2nd char) */
- if( gettingDirectories ) {
- if( (buffer[21]&0x10) != 0 ) /* a directory */
- /* directories will sort to the beginning */
- fileMarks = "DD";
- else
- /* get only directories this pass */
- goto getNextFileName;
- } else {
- if( (buffer[21]&0x3) != 0 )
- /* hidden or read-only files */
- fileMarks = "ZH";
- else
- fileMarks = "ZN";
- }
-
- /* move the name into the buffer */
- offset = 64 * fileCount;
- /* put in the char to make directories sort in front */
- movedata(segRegs.ds, (int)fileMarks, space, offset++, 1);
-
- if( fileSort == 2 ) {
- /* find the extension */
- q = NULL;
- p = &buffer[30];
- while( *p != '\0' ) {
- if( *p == '.' )
- q = p;
- ++p;
- }
- /* found a '.' that was not a ".."? */
- i = 0;
- if( q != NULL && buffer[30] != '.' ) {
- /* remove the extension from the name by */
- /* overlaying the '.' with end-of-string */
- *q++ = '\0';
- /* get the extension */
- while( *q != '\0' )
- extension[i++] = *q++;
- }
- /* pad extension with blanks */
- extensionLength = i;
- while( i < 3 )
- extension[i++] = ' ';
- movedata(segRegs.ds, (int)(&extension[0]), space,
- offset, 3);
- offset += 3;
- }
-
- n = strlen(fileName) + 1; /* + 1 for the '\0' */
- if( fileSort == 2 && extensionLength > 0 ) {
- n -= (extensionLength + 1);
- /* +1 for the "." */
- /* erase the extension from fileName */
- fileName[n - 1] = '\0';
- }
- /* put in the file type chararacter */
- fileName[n] = *(fileMarks + 1);
- movedata( segRegs.ds, (int)fileName, space, offset, n+1 );
- k = n + 1; /* extra +1 for spacing on screen */
- if( k > maxNameSize )
- maxNameSize = k;
- ++fileCount;
-
- getNextFileName:
- /* find the next matching file name */
- fileName = findNextPatternFile(buffer);
- }
-
- /* adjust for the size of the extension if sorting by extension */
- if( fileSort == 2 )
- maxNameSize += 4;
- /* sort the names */
- if( fileSort != 0 ) {
- for(k = 1; k < fileCount; k++) {
- movedata(space, 64*k, segRegs.ds, (int)(&msgBuffer[0]),
- maxNameSize);
- i = k-1;
- while( i >= 0 ) {
- movedata(space, 64*i, segRegs.ds,
- (int)(&textBuffer[0]), maxNameSize);
- if( strcmp(textBuffer, msgBuffer) <= 0 )
- break;
- movedata(segRegs.ds, (int)(&textBuffer[0]),
- space, 64*(i+1), maxNameSize);
- i--;
- }
- movedata(segRegs.ds, (int)(&msgBuffer[0]), space, 64*(i+1),
- maxNameSize);
- }
- }
-
- firstName = 0;
- selectedRow = 0;
- selectedCol = 0;
- doPaging:
- /* clear the screen buffer where the names will go */
- setMap(0, 0, scrRows-2, scrCols-1, 2, textColor);
-
- /* fill in the names */
- n = firstName;
-
- /* maxNameSize has two blanks included in it so adjust for that */
- maxCol = scrCols - (maxNameSize - 2);
- for(col = 0; col < maxCol; col += maxNameSize) {
- for(row = 2; row < scrRows-1; row++) {
- if( n >= fileCount ) {
- lastName = fileCount;
- goto displayNames;
- }
- movedata(space, 64*n, segRegs.ds,
- (int)(&textBuffer[0]), 64);
-
- k = 0; /* k counts screen character positions */
- if( textBuffer[0] == 'D' )
- ret = selColor; /* directory */
- else
- ret = textColor; /* ordinary file */
-
- /* is this filename selected? */
- if( row == selectedRow && col == selectedCol )
- ret = selColor; /* selected */
- else
- ret = textColor; /* not selected */
-
- i = (fileSort==2) ? 4 : 1;
- for( ; textBuffer[i] != '\0'; ++i)
- displayChar(row, col+k++,
- tolower(textBuffer[i]), ret);
- iBuffer = i + 1;
- if( fileSort == 2 && textBuffer[1] != ' ' ) {
- displayChar(row, col+k++, '.', ret);
- for(i = 1; i<4 && textBuffer[i]!=' '; i++)
- displayChar(row, col+k++,
- tolower(textBuffer[i]), ret);
- }
- if( textBuffer[iBuffer] == 'D' )
- displayChar(row, col+k, '\\', ret);
- else if( textBuffer[iBuffer] == 'H' )
- displayChar(row, col+k, '*', ret);
- ++n;
- }
- }
- lastName = n;
-
- displayNames:
- /* remember these so that we can detect invalid click locations */
- saveRow = row;
- saveCol = col;
- (void)getcwd(&msgBuffer[0], MSGBUFFERSIZE);
- sprintf(textBuffer, "%d files in %s matching %s%s",
- fileCount, msgBuffer, filePattern,
- (fileCount < maxFiles ? "" : "SOME FILE NAMES MISSING")
- );
- col = 0;
- for(i = 0; textBuffer[i] != '\0' && col < scrCols; i++)
- displayChar(1, col++, textBuffer[i], bannerColor);
- while( col < scrCols )
- displayChar(1, col++, ' ', bannerColor);
- pulldown(fsMenu);
- updateScreen(0, scrRows-2);
- fileName = getInput(prompt, "", 2);
-
- if( fileName != NULL ) /* A string was entered (no mouse button) */
- goto processFilename;
-
- /* otherwise we got a mouse click and row and col are set */
- /* normalize to first char in field */
- if( nameRow > 0 ) {
- /* normalize to first character in field */
- nameCol = maxNameSize*(nameCol/maxNameSize);
-
- /* see if the click is where we put a file name */
- if( (nameCol > saveCol) || (nameRow == scrRows-1)
- || ((nameCol == saveCol) && (nameRow > saveRow)) ) {
- /* if not, CD to the parent directory */
- strcpy(scratchFileName, "..");
- goto changeDirectory;
- }
-
- #ifdef XXXXXX
- FOR NOW WE WILL ONLY REQUIRE A SINGLE CLICK
-
- /* We require a double click on the name. */
- /* The first selects the filename and the second */
- /* picks the filename for loading into the window */
- if( nameRow != selectedRow || nameCol != selectedCol ) {
- selectedRow = nameRow;
- selectedCol = nameCol;
- goto doPaging;
- }
- #endif
-
- /* now pick up the filename from the screen buffer */
- iBuffer = 0; /* next char in buffer */
- ip = (unsigned int *)&fp;
- *ip++ = (scrCols<<1)*nameRow + 2*nameCol;
- *ip = dispMemory;
- if( *fp == ' ' ) /* don't allow empty filenames */
- goto doPaging;
- while( *fp != ' ' ) {
- scratchFileName[iBuffer++] = *fp;
- fp += 2;
- }
-
- /* if it ends with a '\' it is a directory name */
- /* so change to that directory */
- if( scratchFileName[iBuffer-1] == '\\' ) {
- scratchFileName[iBuffer-1] = '\0';
- changeDirectory:
- chdir(scratchFileName);
- goto restart;
- }
- else if( scratchFileName[iBuffer-1] == '*' )
- /* eliminate the read-only flag '*' */
- scratchFileName[iBuffer-1] = '\0';
- else
- scratchFileName[iBuffer] = '\0';
-
- /* create the full path name, unless it already is one */
- if( scratchFileName[0] != '\\'
- && scratchFileName[1] != ':'
- && scratchFileName[2] != '\\'
- ) {
- /* prepend the pathname of the current directory */
- (void)getcwd(textBuffer, MSGBUFFERSIZE);
- n = strlen(textBuffer) - 1;
- if( textBuffer[n] != '\\' )
- strcat(textBuffer, "\\");
- strncat(textBuffer, scratchFileName, FILENAMESIZE);
- /* copy it back into scratchFileName where it will */
- /* not be changed by other editor activity */
- strcpy(scratchFileName, textBuffer);
- }
- if( iBuffer != 0 )
- fileName = &scratchFileName[0];
- } else if( 0 == nameRow ) { /* menu selection */
- /* figure out which item on the menu */
- n = menus[fsMenu]->nItems;
- col = 0;
- for(i = 1; i < n-1; i++) {
- col += farStrlen(menus[fsMenu]->cmdName[i]);
- if( col > nameCol )
- break;
- }
- n = menus[fsMenu]->cmdNumber[i];
- GotNewN:
- switch( n ) {
-
- default:
- goto doPaging;
-
- /* change directory and/or drive */
- case 1: case 2: case 3: case 4: case 5:
- case 6: case 7: case 8: case 9: case 10:
- case 11: case 12: case 13: case 14: case 15:
- case 16: case 17: case 18: case 19: case 20:
- CopyNthPattern(n-1, fsDirs, &textBuffer[0]);
- if( textBuffer[1] == ':' ) {
- setDefaultDrive(toupper(textBuffer[0])-'A');
- k = 2;
- } else
- k = 0;
- if( textBuffer[k] != '\0' )
- chdir(&textBuffer[k]);
- goto restart;
-
-
- /* change filePattern to a set file pattern */
- case 21: case 22: case 23: case 24: case 25:
- case 26: case 27: case 28: case 29: case 30:
- case 31: case 32: case 33: case 34: case 35:
- case 36: case 37: case 38: case 39: case 40:
- CopyNthPattern(n-21, &fsPatterns[0], &filePattern[0]);
- goto restart;
-
- /* drop down a menu */
- case 41: case 42: case 43: case 44: case 45:
- case 46: case 47: case 48: case 49: case 50:
- case 51: case 52: case 53: case 54: case 55:
- case 56: case 57: case 58: case 59: case 60:
- n = menu(menus[n-40], 1, nameCol);
- goto GotNewN;
-
- /* change the file sorting */
- case 61: case 62: case 63:
- fileSort = n - 61;
- goto restart;
-
- case 64: /* next page */
- if( lastName < fileCount )
- firstName = lastName;
- else
- firstName = 0;
- goto doPaging;
-
- case 65: /* previous page */
- n = (scrRows-4)*((scrCols+2)/maxNameSize);
- firstName -= n;
- if( firstName < 0 )
- firstName = 0;
- goto doPaging;
-
- case 66: /* new file pattern */
- p = getInput("New file pattern: ", "*.*", 3);
- if( p != NULL )
- strcpy(filePattern, p);
- goto restart;
-
- case 67: /* cancel load */
- goto cancelLoad;
-
- case 68: /* goto to Point startup directory */
- setDefaultDrive(startDrive);
- chdir(startDirectory);
- goto restart;
- case 69: /* new drive or directory */
- p = getInput("New drive and/or directory: ",
- "C:\\", 3);
- if( p != NULL ) {
- if( p[1] == ':' ) {
- setDefaultDrive(toupper(p[0])-'A');
- k = 2;
- } else
- k = 0;
- if( p[k] != '\0' )
- chdir(&p[k]);
- }
- goto restart;
-
- }
- } else
- goto cancelLoad;
-
- askName:
- /* if we didn't get a name -- ask for one */
- if( fileName == NULL )
- fileName = getInput(prompt, "", 3);
- /* do not process the filename since it is already a full pathname */
- goto cancelLoad;
- processFilename:
- /* capture the full pathname using the drive and directory */
- /* before we change it back to the startup drive and directory */
- fileName = makeFullPathname(fileName);
-
- cancelLoad:
- /* restore the screen */
- redrawBox(0, 0, scrRows-1, scrCols-1);
- updateScreen(0, scrRows-1);
-
- /* release the allocated space */
- if( space != NULL ) {
- rin.h.ah = 0x49;
- segread(&sr);
- sr.es = space;
- intdosx(&rin, &rout, &sr);
- }
- helpMode = saveHelpMode;
-
- /* remember the user's current directory and drive */
- (void)getcwd(¤tDirectory[0], FILENAMESIZE);
- currentDrive = getDefaultDrive();
-
- /* and return to the startup drive and directory */
- setDefaultDrive(startDrive);
- chdir(startDirectory);
-
- return fileName;
- }
-
-
- void pascal
- /* XTAG:CopyNthPattern */
- CopyNthPattern(n, patterns, toString)
- int n;
- unsigned char far *patterns;
- unsigned char *toString;
- /* patterns starts and ends with " */
- /* it contains 0 or more patterns separated with ";"s */
- /* skip "n" patterns (that is, skip "n" ";"s) and then */
- /* copy the next pattern into "toString" */
- {
- register unsigned char ch;
- register unsigned char *p;
-
- p = &patterns[1]; /* skip the initial " */
- /* scan past n ";"s */
- while( n-- > 0 ) {
- /* find the next ";" */
- while( 1 ) {
- ch = *p++;
- if( ch == ';' )
- break;
- if( ch == '\0' ) {
- /* not enough patterns so */
- /* just use the first one */
- p = &patterns[1]; /* skip initial " */
- goto noMorePatterns;
- }
- }
- }
- noMorePatterns:
- while( 1 ) {
- ch = *p++;
- if( ch == ';' || ch == '\0' || ch == '"' )
- break;
- *toString++ = ch;
- }
- *toString = '\0';
- }
-
-
- #ifdef QUICKSORT
- /********************* QUICKSORT *************************************/
- #define splitter &textBuffer[0]
- #define item &textBuffer[64]
- #define temp &textBuffer[128]
-
- void pascal
- /* XTAG:qsort */
- qsort(low, high)
- int low, high;
- {
- extern unsigned char msgBuffer[];
- extern unsigned char textBuffer[];
- extern struct SREGS segRegs;
-
- int mid, i, lastLow;
-
- /* if there are 1 or fewer items to sort, we are already done! */
- if( low >= high )
- return;
-
- /* pick the middle item and swap it with the first item */
- mid = (high+low)/2; /* or mid = randint(low,high) */
-
- /* pick up the splitting item */
- movedata(space, 64*mid, segRegs.ds, splitter, maxNameSize);
-
- /* copy the first element into the mid slot */
- movedata(space, 64*low, temp, maxNameSize);
- movedata(segRegs.ds, temp, space, 64*mid, maxNameSize);
-
- /* copy the splitting item into the low slot */
- movedata(segRegs.ds, splitter, space, 64*low, maxNameSize);
-
- lastLow = low;
- for(i = low+1; i <= high; i++) {
- /* get the item in slot i */
- movedata(space, 64*i, segRegs.ds, item, maxNameSize);
- /* compare against the splitting element */
- if( strcmp(item, splitter) < 0 ) {
- /* if it is lower than the splitter, */
- /* exchange it with ++lastLow */
- ++lastLow;
- movedata(space, 64*lastLow,
- segRegs.ds, temp, maxNameSize);
- movedata(segRegs.ds, item, space, 64*lastLow,
- maxNameSize);
- movedata(segRegs.ds, temp, space, 64*i, maxNameSize);
- }
- }
- movedata(space, 64*lastLow, segRegs.ds, temp, maxNameSize);
- movedata(segRegs.ds, temp, space, 64*low, maxNameSize);
- movedata(segRegs.ds, splitter, space, 64*lastLow, maxNameSize);
-
- /* Reduce the stack growth by doing the shortest one first. */
- /* This always keeps the longer intervals on the stack and */
- /* there must necessarily be fewer intervals if they are longer. */
- if( low < lastLow )
- qsort(low, lastLow-1);
- if( lastLow+1 < high )
- qsort(lastLow+1, high);
- }
- /************************* END QUICKSORT *****************************/
- #endif
-
- unsigned char * pascal
- /* XTAG:getInput */
- getInput(prompt, strDefault, oneChar)
- unsigned char *prompt, *strDefault;
- int oneChar;
- {
- extern union REGS rin, rout;
- extern struct window *selWindow;
- extern long selBegin, selEnd;
- extern int debug;
- extern unsigned char msgColor, promptColor;
- extern int scrRows, scrCols;
- extern int evhead, evtail;
- extern struct event events[];
- extern int cursorMouse;
- extern int menuLine;
-
- int i, j, fileId, col;
- int pLen, firstTime, bottomRow;
- int saveCursorMouse, fn;
- long cp;
- unsigned char ch, scan, *retValue;
-
- retValue = buffer;
- pLen = strlen(prompt);
- saveCursorMouse = cursorMouse;
- cursorMouse = 1;
-
- firstTime = 1;
- strncpy(buffer, strDefault, 100);
- i = strlen(buffer);
- bottomRow = scrRows - 1;
- if( menuLine < 0 )
- --bottomRow;
- switch( oneChar ) {
- /* this is the entry that does not erase the prompt */
- case 5:
- firstTime = 0;
- oneChar = 0;
- break;
- /* these signify that getFileName called */
- case 4:
- case 3:
- oneChar -= 3;
- case 2:
- if( menuLine < 0 )
- ++bottomRow;
- break;
- }
-
- /* each iteration picks up a keystroke or mouse click */
- while( 1 ) {
- /* redraw the prompt and input line so far */
- setMap(bottomRow, 1, bottomRow, 78, 0, msgColor);
- col = 1;
- j = 0;
- while( 1 ) {
- ch = prompt[j++];
- if( ch == '\0' || col > 78 )
- break;
- displayChar(bottomRow, col++, ch, msgColor);
- }
- j = 0;
- while( j < i ) {
- ch = buffer[j++];
- displayChar(bottomRow, col++, ch, promptColor);
- }
- updateScreen(bottomRow, scrRows-1);
-
- /* wait for a keystroke or mouse button */
- while( 1) {
- if( isKeystroke() != 0 ) {
- ch = getKeystroke(&scan);
- fn = translateKey(ch, scan);
- /* if cursor returns 1 then it was a cursor */
- /* movement character and so do not put it */
- /* in the string */
- if( cursor(fn, 0) )
- continue;
- break;
- }
- if( isMouseEvent(0) ) { /* mouse event? */
- /* get the current mouse position */
- evhead = getMouseEvent();
- j = events[evhead].buttons;
- if( oneChar == 2 && j != 0 ) {
- retValue = NULL;
- /* return values to getFileName */
- nameRow = events[evhead].vertical>>3;
- nameCol =
- events[evhead].horizontal>>3;
- buttonState = j;
- goto ret;
- }
- if( oneChar == 1 && j != 0 ){
- #ifdef HARDCONFIRMS
- /* only confirm on bottom row */
- if( (events[evhead].vertical>>3)
- < bottomRow )
- continue;
- #endif
- ch = (unsigned char)
- ((j == 1) ? 'y' : 'n');
- break; /* since we got the one */
- /* character we need */
- } else if( j == 1 )
- goto newLine;
- else if( j == 2 ) { /* right mouse button */
- /* clear the default if there are */
- /* no other keystrokes */
- if( firstTime ) {
- firstTime = 0;
- i = 0;
- }
- /* copy selection into the string */
- cp = selBegin;
- fileId = selWindow->fileId;
- while( 1 ) {
- ch = readChar(fileId, cp++);
- if( cp > selEnd )
- break;
- buffer[i++] = ch;
- if( i >= 100 )
- --i;
- }
- break;
- }
- }
- }
- switch( ch ) {
-
- case '\33': /* ESCape */
- retValue = NULL;
- /* this signals getFileName that the load was */
- /* cancelled */
- nameRow = -1;
- goto ret;
-
- case '\b':
- if( i > 0 )
- --i;
- break;
-
- case '\177': /* ascii del -- control-backspace */
- i = 0;
- break;
-
- case '\r':
- newLine:
- buffer[i] = '\0';
- goto ret;
-
- default:
- if( firstTime )
- i = 0;
- buffer[i++] = ch;
- if( i >= 100 )
- --i;
- if( oneChar == 1 )
- goto ret;
- break;
- }
- firstTime = 0;
- }
- ret:
- if( bottomRow == (scrRows - 1) )
- msg("", 1);
- cursorMouse = saveCursorMouse;
-
- return retValue;
- }
-