diff options
Diffstat (limited to 'systems/msdos/tx/src/txdir.c')
-rw-r--r-- | systems/msdos/tx/src/txdir.c | 352 |
1 files changed, 352 insertions, 0 deletions
diff --git a/systems/msdos/tx/src/txdir.c b/systems/msdos/tx/src/txdir.c new file mode 100644 index 0000000000..5e4ca371c0 --- /dev/null +++ b/systems/msdos/tx/src/txdir.c @@ -0,0 +1,352 @@ +#include "tx.h" +#include <dos.h> + +char *FName[MAX_FILES_IN_DIR] ; +int num; + +void TxDir(void) +{ + struct ffblk FFind ; + int i,j,selection,memidx=0,baddrv=0 ; + int row,col,oldrive,DosDrives,DrivesShown=0 ; + char *TextInWindow , *TextInLine, NameSel[15], NewPath[MAXPATH] ; + char *FMem[1+(MAX_FILES_IN_DIR/40)]; + void krqsort (int,int); + int ShowFiles(void) ; + void AppendStars(char *) ; /* apppend *.* to path */ + int StripStars(char *) ; + int DriveExists[26]; + void TestDrives(int *,int *,int *); + extern void DrawFrame(int,int,int,int,int); + + oldrive = CurrDrive ; + strcpy(NewPath,Path) ; + AppendStars(NewPath) ; + + for (i=0;i<26;i++) /* Initialize */ + DriveExists[i]=0; + + TestDrives(DriveExists,&DosDrives,&DrivesShown); + --DrivesShown; + + row = wherey() ; col = wherex() ; /* Save cursor position */ + _setcursortype(_NOCURSOR) ; /* Hide cursor */ + + TextInWindow = malloc(757); + gettext(3,3,20,23,TextInWindow); + TextInLine = malloc(161); + gettext(1,2,80,2,TextInLine); + + window(3,3,20,23) ; /* L T R B */ + clrscr() ; /* Clear text in window area */ + window(1,1,80,25) ; /* But work in absolute coordinates */ + DrawFrame(3,3,20,23,0) ; /* Draw window frame (single) */ + + do { /* Start of main loop */ + + if ( DrivesShown ) + FName[0]=FMem[0]=malloc(5*DrivesShown); + + for ( i=1 ; i < DrivesShown ; i++ ) + FName[i] = FName[i-1] + 5 ; + + for ( i=0,j=0 ; i < DrivesShown ; i++ ) { + strcpy(FName[i],"<A:>") ; + for ( ; (!DriveExists[i+j])||((i+j)==CurrDrive) ; j++) ; + *(FName[i]+1) = i + j + 'A' ; + } + /* Start mem index at 0 if only 1 drive, 1 otherwise */ + memidx = DrivesShown ? 1 : 0 ; + i = findfirst(NewPath,&FFind,FA_DIREC) ; + + for ( num=DrivesShown ; + (i==0) && (num < MAX_FILES_IN_DIR) ; num++ ) { + if ( ( (num-DrivesShown) % 40) == 0 ) { + FName[num] = FMem[memidx++] = malloc(600); + for ( j = 1 ; j < 40 ; j++ ) + FName[num+j] = FName[num] + (j * 15) ; + } + if ( FFind.ff_attrib & FA_DIREC ) { + *(FName[num]) = '[' ; /* Enclose directories in brackets */ + strcpy(FName[num]+1,FFind.ff_name) ; + strcat(FName[num],"]") ; + } + else + strcpy(FName[num],FFind.ff_name) ; + i = findnext(&FFind) ; + } + /* num contains number of files in directory + actual logical drives */ + /* memidx contains de number of times malloc has been called */ + + /* We now have all names in FName. Drives are enclosed in <> + and directories in []. Drives are already ordered, so we + may forget about them. Directories and files will be sorted + separately, namely, the [ will precede other characters in + the lexicographic order we use. To help avoiding problems + in case of a future change, we also make < the character + with the highest precedence. */ + + /* Sorting procedure borrowed from K&R */ + krqsort(DrivesShown,num-1); + + puttext(1,2,80,2,TextInLine) ; + gotoxy(4,2) ; + cputs(NewPath) ; + if ( (selection = ShowFiles()) == -1 ) + break ; + strcpy(NameSel,FName[selection]) ; + for ( j=0 ; j < memidx ; j++ ) + free(FMem[j]) ; + if (!( ( *NameSel == '[' ) || ( *NameSel == '<' )) ) + break ; /* A file has been selected */ + if (!strcmp(NameSel,"[.]") ) /* current directory */ + continue ; /* reread current directory */ + i = StripStars(NewPath) ; + if ( !strcmp(NameSel,"[..]") ) { /* parent directory */ + for (; (i-3) && (NewPath[i] != BACKSLASH );i-- ) ; + NewPath[i] = '\0' ; + chdir(NewPath) ; + } + else if ( *NameSel == '[' ) { /* Another directory */ + if ( i-3 ) + NewPath[i++] = BACKSLASH ; + for (j=0 ; (NewPath[i]=NameSel[++j])!=']';i++); + NewPath[i]='\0' ; /* get rid of terminating ] */ + chdir(NewPath) ; + } + else { /* Now NameSel[0] equals '<', so we change drive */ + CurrDrive = ( (int) NameSel[1] ) - 'A' ; + setdisk(CurrDrive) ; /* set disk */ + NewPath[0]='\0'; + if ( getcwd(NewPath,MAXPATH)==NULL ) { + baddrv = 1 ; + selection = -1 ; + break; + } + } + AppendStars(NewPath) ; + + } while (1) ; /* End of main loop */ + + + /* Restore settings */ + puttext(3,3,20,23,TextInWindow) ; + free(TextInWindow) ; + puttext(1,2,80,2,TextInLine) ; + free(TextInLine) ; + _setcursortype(_NORMALCURSOR) ; /* show cursor */ + gotoxy(col,row) ; /* restore cursor position */ + + if (selection == -1 ) { /* Leave everything as before */ + if ( !baddrv ) + for ( j=0 ; j < memidx ; j++ ) + free(FMem[j]) ; + setdisk(oldrive) ; + CurrDrive = oldrive ; + chdir(Path) ; + return ; + } + + i=StripStars(NewPath) ; + strcpy(Path,NewPath) ; + if ( Path[--i] != BACKSLASH ) + Path[++i] = BACKSLASH; + for (j=0 ; ( Path[++i] = NameSel[j++] ) ; ); + SplitPath(); +} + + + +int ShowFiles(void) +{ + int i,j,init=0,last ; + int previous=0, current = 0 ; + + while ( previous != -1 ) { + previous = 0 ; + last = ( init + 19 < num ) ? init + 18 : num - 1 ; + window(5,4,18,22) ; + clrscr() ; + window(1,1,80,25) ; + + for ( i = init ; i <= last ; i++ ) { + gotoxy(5,4+(i-init)) ; + cputs(FName[i]) ; + } + + while ( previous >= 0 ) { + while (1) { /* Highlight currently selected entry */ + textattr(color[(previous == current)]) ; + gotoxy(5,4+previous) ; + cputs(FName[init+previous]) ; + j = 14 - strlen(FName[init+previous]) ; + while ( j-- ) + putch(' ') ; + if ( previous == current ) break ; + previous = current ; + } + textattr(color[0]) ; + i = getch(); /* Read character from keyboard */ + if ( i == 0 ) { /* If extended character */ + i = getch() ; /* Get character */ + i *= -1 ; /* Make it different from regular ascii */ + } + switch ( i ) { + case CR : + previous = -1 ; /* Choose current entry */ + break ; + case HOMEKEY : + if ( init > 0 ) { + init = 0 ; + previous = -2 ; + } + current = 0 ; /* Go to first entry */ + break ; + case ENDKEY : + last = num-1 ; /* Go to last entry */ + previous = -2 ; + init = ( num > 18 ) ? last - 18 : 0 ; + current = last - init ; + break ; + case UPKEY : + case LEFTKEY : + if ( current ) + --current ; /* Move up one position */ + else if (init) { + --init ; /* Scroll back one position */ + previous = -2 ; + } + break ; + case DOWNKEY : + case RIGHTKEY : + if ( init+current < last ) + ++current ; /* Move down one position */ + else if ( last+1 < num ) { + ++init ; /* Scroll forward one position */ + previous = -2 ; + } + break ; + case PGUPKEY : + if (init==0) + current = 0; + else if (init > 17 ) { + init -= 18 ; + /* current = 18 ; Leave current as it is now */ + previous = -2 ; + } + else { + current = init ; + init = 0 ; + previous = -2 ; + } + break ; + case PGDNKEY : + if ( last+1 >= num ) + current = last - init ; + else { + init = last ; + if ( last + current > num - 1 ) + current = num - (last+1) ; + previous = -2 ; + } + break ; + default : + previous = -1 ; + current = -1 ; + break ; + } /* switch (i) */ + } /* while (previous >= 0) */ + } /* while (previous != -1) */ + if ( current == -1 ) + return -1 ; + else + return init+current ; +} + + +void krqsort (int krleft, int krright) +{ + int kri,krlast; + void krswap(int,int) ; + int krcomp(char *,char *); + + if (krleft >= krright ) + return; + krswap(krleft,(krleft+krright)/2); + krlast=krleft; + for (kri=krleft+1;kri<=krright;kri++) + if (krcomp(FName[kri],FName[krleft])<0) + krswap(++krlast,kri); + krswap(krleft,krlast); + krqsort(krleft,krlast-1); + krqsort(krlast+1,krright); +} + +void krswap(int ki,int kj) +{ + char *temp; + temp=FName[ki]; FName[ki]=FName[kj];FName[kj]=temp; +} + +/* Lexicographical comparison, but giving priority to + the drive symbols "<" and to the directory symbols "[". */ + +int krcomp(char *a, char *b) +{ + for ( ; *a == *b ; a++, b++ ) + if ( *a == '\0' ) + return 0 ; + if ( *a == '<' ) return -1 ; + else if ( *b == '<' ) return 1 ; + else if ( *a == '[' ) return -1 ; + else if ( *b == '[' ) return 1 ; + else return *a - *b ; +} + + +void TestDrives(int *DriveExists,int *DosDrives, int *ValidDrives) +{ + int i; + union REGS r; + + *DosDrives=setdisk(CurrDrive); + *ValidDrives=0; + + for ( i=0; i< *DosDrives; i++) { + setdisk(i); + DriveExists[i] = ( i == getdisk() ) ; + if (DriveExists[i]) { + r.x.ax = 0x440E; + r.x.bx = 0; + intdos(&r,&r); + if ((!( r.x.flags & 1 )) && (r.x.ax & 0xFF)&& + (r.x.ax & 0xFF) != i+1 ) + DriveExists[i]= 0; /* Drive already referenced */ + } + *ValidDrives += DriveExists[i]; + } + setdisk(CurrDrive) ; /* Restore current disk after tests */ +} + + +void AppendStars(char *Pname) +{ + for (; *Pname ; Pname++) ; /* go to end of string */ + if (*--Pname != BACKSLASH ) /* make sure last char is a backslash */ + *++Pname = BACKSLASH ; + *++Pname = '*' ; + *++Pname = '.' ; + *++Pname = '*' ; + *++Pname = '\0' ; +} + +int StripStars(char *Pname) +{ + int i; + for (i=0; *Pname!='*' ; i++,Pname++) ; + --Pname; /* Point to backslash */ + if (*--Pname == ':' && ++i ) + ++Pname; + *++Pname = '\0' ; + return --i; +} |