summaryrefslogtreecommitdiff
path: root/systems/msdos/tx/src/txdir.c
diff options
context:
space:
mode:
Diffstat (limited to 'systems/msdos/tx/src/txdir.c')
-rw-r--r--systems/msdos/tx/src/txdir.c352
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;
+}