page@swan.ulowell.edu (Bob Page) (03/16/89)
Submitted-by: alliant!mistress!berry (Steve -Raz- Berry) Posting-number: Volume 89, Issue 51 Archive-name: workbench/flist12.3 # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # sort.c # ttyicon.c # ttyio.c # This archive created: Wed Mar 15 12:12:50 1989 cat << \SHAR_EOF > sort.c /* The Sorting routines live here. I used the quick sort algorithm as implimemted by Manx to sort a list of indices, and then I rearranged the data to conform to the sorted list. In order to do the sort, there must be one free element available in the array. Written by Steve (Raz) Berry. 1/8/89 */ #include "flist.h" #include <libraries/arpbase.h> extern long (*finfo[MAXDIR])[4]; extern char (*fname[MAXDIR])[FCHARS]; extern char (*comm[MAXDIR])[FCHARS]; extern char (*fstring[MAXDIR])[LEN_DATSTRING]; extern char (*ftime[MAXDIR])[LEN_DATSTRING]; extern long numfiles, top, row, line; extern struct AnchorPath *ap; extern char strbuf[256]; extern void swap(); long lastsort = -1; sort(which) int which; { if (numfiles > MAXDIR -1) { auto_req("Can't sort list - No space"); return; } switch (which) { case 0: sortname(); lastsort = 0; break; case 1: sortsize(); lastsort = 1; break; case 2: sortdate(); lastsort = 2; break; case 3: sortpattern(); break; case 4: sortday(); lastsort = 4; break; } } cmp(s1,s2) long *s1, *s2; { return Strcmp(fname[*s1], fname[*s2]); } sortname() { long list[MAXDIR]; register long i; for (i = 0;i<numfiles;i++) list[i] = i; qsort(list, numfiles, 4L, cmp); sortme(list); } cmp1(s1,s2) long *s1,*s2; { return ((*finfo[*s1])[2] > (*finfo[*s2])[2]) ? 1 : ((*finfo[*s1])[2] < (*finfo[*s2])[2]) ? -1 : 0; } sortsize() { long list[MAXDIR]; register long i; for (i = 0;i < numfiles;i++) list[i] = i; qsort(list, numfiles, 4L, cmp1); sortme(list); } cmp2(s1,s2) long *s1, *s2; { return Strcmp(ftime[*s1], ftime[*s2]); } sortdate() { long list[MAXDIR]; register long i; for (i = 0;i < numfiles;i++) list[i] = i; qsort(list, numfiles, 4L, cmp2); sortme(list); } cmp3(s1,s2) long *s1, *s2; { return Strcmp(fstring[*s1], fstring[*s2]); } sortday() { long list[MAXDIR]; register long i; for (i = 0;i < numfiles;i++) list[i] = i; qsort(list, numfiles, 4L, cmp3); sortme(list); } /* Here we sort by pattern... actually we just reget the directory based on the input string. */ long sortpattern() { char buf[256]; struct Window *strptr; long rc; strbuf[0] = '\0'; strptr = make_gadget("Enter search Pattern"); if (strptr == NULL) { auto_req("Couldn't open Requestor!"); return BAD_COMMAND; } drawcur(); wait_for_event(strptr); blankcur(); if (strbuf[0] == '\0') return NULL; rc = FindFirst(strbuf,ap); if (rc == NULL){ Fillarray(); /* fill the arrays with the names and info */ top = 0; row = 0; line = 0; } else { if (rc != ERROR_NO_MORE_ENTRIES){ sprintf(buf,"Bad pattern -%s- !",strbuf); auto_req(buf); FindFirst("*",ap); Fillarray(); top = 0; row = 0; line = 0; } else numfiles = 0; } return rc; } /* Here's the deal... Now that I have the list of indices all sorted, I figured that arranging the list to match the indices would be simple. WRONG. This was the hardest part by far. Next time I will arrange my arrays as structures and sort them in place. I'll probably also use a Heapsort routine (it's a better general purpose routine) as well. */ /* More sorting for the resultant list */ find(index, list) long list[MAXDIR]; { register long i; #ifdef DEBUG if (index <0){ auto_req("index of -1!"); return 0; } #endif for (i=0;index != list[i];i++); return i; } swapall(one, two) long one, two; { swap(&finfo[one], &finfo[two]); swap(&fname[one], &fname[two]); swap(&comm[one], &comm[two]); swap(&fstring[one], &fstring[two]); swap(&ftime[one], &ftime[two]); } /* This routine actually rearanges the list into the proper order */ sortme(list) long list[MAXDIR]; { register long sa, pos, i; long first = -1,index; sa = numfiles; index = 0; while(1) { for(i=0;((list[i] == -1) || (list[i] == i)) && (i < numfiles);i++); if (i >= numfiles) break; index = i; first = -1; for (i=0;i<numfiles;i++) { /* prime the pipe */ pos = find(index, list); if (pos != index) { if (first == -1) first = index; swapall(index, pos); swapall(index, sa); list[pos] = -1; index = pos; } else list[index++] = -1; if (first != -1) break; } for (i=0;pos != first;i++) { /* follow the thread to the end */ pos = find(index, list); swapall(sa, pos); list[pos] = -1; index = pos; } } } SHAR_EOF cat << \SHAR_EOF > ttyicon.c /* * Iconify the Flist window using Leo Schwab's iconify() routine. * */ #include <intuition/intuition.h> #include "icon/iconify.h" extern struct Screen *scrptr; UWORD flicon_data[] = { /* BitPlane #0 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7FFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xC000, 0x7FFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xC000, 0x7FFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xC000, 0x7C00, 0x0000, 0x0000, 0x000F, 0xC000, 0x7C00, 0x0000, 0x0000, 0x000F, 0xC000, 0x7C1F, 0xE783, 0x8001, 0x800F, 0xC000, 0x7C0E, 0xE380, 0x0003, 0x800F, 0xC000, 0x7C0E, 0x0387, 0x87E7, 0xE00F, 0xC000, 0x7C0F, 0x8383, 0x8E03, 0x800F, 0xC000, 0x7C0E, 0x0383, 0x87C3, 0x800F, 0xC000, 0x7C0E, 0x0383, 0x80E3, 0xE00F, 0xC000, 0x7C1F, 0x07C7, 0xCFC1, 0xC00F, 0xC000, 0x7C00, 0x0000, 0x0000, 0x000F, 0xC000, 0x7C00, 0x0000, 0x0000, 0x000F, 0xC000, 0x7C00, 0x0000, 0x0000, 0x000F, 0xC000, 0x7C00, 0x0000, 0x1E00, 0x000F, 0xC000, 0x7C00, 0x0000, 0x0E00, 0x000F, 0xC000, 0x7C00, 0x07EE, 0x7FC0, 0x000F, 0xC000, 0x7C00, 0x0E0F, 0xFFE0, 0x000F, 0xC000, 0x7C00, 0x07CF, 0xFEE0, 0x000F, 0xC000, 0x7C00, 0x00E7, 0xEEE0, 0x000F, 0xC000, 0x7C00, 0x0FC7, 0xE7C0, 0x000F, 0xC000, 0x7C00, 0x0000, 0x0000, 0x000F, 0xC000, 0x7C00, 0x0000, 0x0000, 0x000F, 0xC000, 0x7C00, 0x0000, 0x0000, 0x000F, 0xC000, 0x7C00, 0x0000, 0x0000, 0x000F, 0xC000, 0x7C00, 0x0000, 0x0000, 0x000F, 0xC000, 0x7C00, 0x0000, 0x0000, 0x000F, 0xC000, 0x7C00, 0x0000, 0x0000, 0x000F, 0xC000, 0x7C00, 0x0000, 0x0000, 0x000F, 0xC000, 0x7FFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xC000, 0x7FFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xC000, 0x7FFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xC000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* BitPlane #1 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7FFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xC000, 0x4000, 0x0000, 0x0000, 0x0000, 0x4000, 0x4000, 0x0000, 0x0000, 0x0000, 0x4000, 0x43FF, 0xFFFF, 0xFFFF, 0xFFF0, 0x4000, 0x43FF, 0xFFFF, 0xFFFF, 0xFFF0, 0x4000, 0x43FF, 0xFFFF, 0xFFFF, 0xFFF0, 0x4000, 0x43FF, 0xFFFF, 0xFFFF, 0xFFF0, 0x4000, 0x43FF, 0xFFFF, 0xFFFF, 0xFFF0, 0x4000, 0x43FF, 0xFFFF, 0xFFFF, 0xFFF0, 0x4000, 0x43FF, 0xFFFF, 0xFFFF, 0xFFF0, 0x4000, 0x43FF, 0xFFFF, 0xFFFF, 0xFFF0, 0x4000, 0x43FF, 0xFFFF, 0xFFFF, 0xFFF0, 0x4000, 0x43FF, 0xFFFF, 0xFFFF, 0xFFF0, 0x4000, 0x43FF, 0xFFFF, 0xFFFF, 0xFFF0, 0x4000, 0x43FF, 0xFFFF, 0xFFFF, 0xFFF0, 0x4000, 0x43FF, 0xFFFF, 0xE1FF, 0xFFF0, 0x4000, 0x43FF, 0xFFFF, 0xF1FF, 0xFFF0, 0x4000, 0x43FF, 0xF811, 0x803F, 0xFFF0, 0x4000, 0x43FF, 0xF1F0, 0x001F, 0xFFF0, 0x4000, 0x43FF, 0xF830, 0x011F, 0xFFF0, 0x4000, 0x43FF, 0xFF18, 0x111F, 0xFFF0, 0x4000, 0x43FF, 0xF038, 0x183F, 0xFFF0, 0x4000, 0x43FF, 0xFFFF, 0xFFFF, 0xFFF0, 0x4000, 0x43FF, 0xFFFF, 0xFFFF, 0xFFF0, 0x4000, 0x43FF, 0xFFFF, 0xFFFF, 0xFFF0, 0x4000, 0x43FF, 0xFFFF, 0xFFFF, 0xFFF0, 0x4000, 0x43FF, 0xFFFF, 0xFFFF, 0xFFF0, 0x4000, 0x43FF, 0xFFFF, 0xFFFF, 0xFFF0, 0x4000, 0x43FF, 0xFFFF, 0xFFFF, 0xFFF0, 0x4000, 0x43FF, 0xFFFF, 0xFFFF, 0xFFF0, 0x4000, 0x4000, 0x0000, 0x0000, 0x0000, 0x4000, 0x4000, 0x0000, 0x0000, 0x0000, 0x4000, 0x7FFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xC000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; UWORD cursor_img[] = { 0xff00,0xff00, 0xff00,0xff00, 0xff00,0xff00, 0xff00,0xff00, 0xff00 }; struct Image cursor_image = { 0, 0, 8, 9, 1, cursor_img, 0x0, 0x4, NULL }; UWORD cursor_empty[] = { 0x0000,0x0000, 0x0000,0x0000, 0x0000,0x0000, 0x0000,0x0000, 0x0000 }; struct Image cursor_blank = { 0, 0, 8, 9, 1, cursor_empty, 0x0, 0x0, NULL }; struct Image flicon_image = { 0, 0, 67, 35, 2, NULL, 0x3, 0x0, NULL }; extern struct Process *myproc; extern struct Window *winptr; int tticon() { static UWORD iconX = 0, iconY = 0; if(scrptr->FirstWindow->NextWindow != NULL) { auto_req("Kill all other Applications first"); return FALSE; } /* hide the window, display the icon, then redisplay the window */ myproc->pr_WindowPtr = (APTR)-1; tthide(FALSE); /* not resizing */ flicon_image.ImageData = &flicon_data[0]; iconify(&iconX, &iconY, flicon_image.Width, flicon_image.Height, NULL, &flicon_image, (int) ICON_IMAGE); /* iconify */ ttshow(FALSE); /* no resize */ myproc->pr_WindowPtr = winptr; return TRUE; } SHAR_EOF cat << \SHAR_EOF > ttyio.c /* This is the I/O stuff for Flist... Inspired by the Mg2a project. Written by Stephen W. Berry. 8/19/88 */ #include <libraries/arpbase.h> #include "flist.h" /* * External Amiga functions. */ extern LONG AbortIO(); extern LONG CloseDevice(); extern struct IOStdReq *CreateStdIO(); extern int OpenConsole(); extern struct Window *OpenWindow(); extern LONG RawKeyConvert(); extern top; /* extern Flist variables */ extern struct NewWindow *winptr; extern struct Window mywin; extern struct NewScreen *scrptr; extern struct Screen scr; extern struct Menu fmenu; extern struct Gadget pg; extern struct RastPort *rp; extern struct Image cursor_image; extern struct Image cursor_blank; extern Enable_Abort; extern struct FileLock *lock, *olddir; extern char (*fname[MAXDIR])[FCHARS]; extern long (*finfo[MAXDIR])[4]; extern short remember; /* Some external functions */ extern void swapdir(), parent(); extern long DoDOS(), spawnproc(), kill(), changedir(); /* Global variables */ struct Device *ConsoleDevice; struct IOStdReq ConsoleReq; struct InputEvent RawKeyEvent = {NULL,IECLASS_RAWKEY,0,0,0}; #define BUFSIZ 10 UBYTE KeyBuffer[BUFSIZ]; struct IntuiText input = { TEXTCOLOR,0, /* Front & Back pen */ JAM2, /* Drawmode */ 0,0, /* Left, Top */ NULL, /* Font */ KeyBuffer, NULL /* Next text */ }; char conline[256]; char titlestr[80]; long row = 0,collum = 0,line = 0,first = 0; void ttclose(),tthide(),ttshow(); /* * Iconify Flist's window using tthide(), iconify(), and ttshow(). */ VOID tthide(resize) int resize; { if (resize == TRUE) { /* if we're resizing, */ mywin.LeftEdge = winptr->LeftEdge; /* use current window size */ mywin.TopEdge = winptr->TopEdge; mywin.Width = winptr->Width; mywin.Height = winptr->Height; } ttclose(); /* reset to zero */ } VOID ttshow(resize) int resize; { openstuff(); SetMenuStrip(winptr, &fmenu); Enable_Abort = 1; } VOID ttclose() { ClearMenuStrip(winptr); CloseWindowSafely(winptr,NULL); CloseScreen(scrptr); winptr = NULL; scrptr = NULL; Enable_Abort = 0; } extern long numfiles, lastsort; refresh() { char buf[100], buf1[200]; remember = -10; collum = 0; if (row+1 > numfiles && row+2 == numfiles) { row--; line--; } else if (row > numfiles) { top = 0; row = 0; line = 0; } sort(lastsort); first = 0; scrprt(NUMLINES,top); PathName(lock, buf1); sprintf(buf,"%s Files = %ld", buf1, numfiles); strncpy(titlestr,buf,80L); SetWindowTitles(winptr, -1L,titlestr); } OpenConsole() { if (OpenDevice("console.device",-1L,&ConsoleReq,0L)){ DisplayBeep(); Cleanup(); } ConsoleDevice = ConsoleReq.io_Device; /* Lib base address */ } /* this little guy takes input from the IDCMP and stuffs it out to the routines involved... */ getkey(message) struct IntuiMessage *message; /* this routine has the potential to grow to enormous */ { /* size... I'll try to restrain myself */ long keycodes,i,rc; char buf[1000]; RawKeyEvent.ie_Code = message->Code; RawKeyEvent.ie_Qualifier = message->Qualifier; RawKeyEvent.ie_position.ie_addr = *((APTR *)message->IAddress); keycodes = RawKeyConvert(&RawKeyEvent,KeyBuffer,BUFSIZ,NULL); ReplyMsg(message); if (keycodes > 0){ /* we have something */ blankcur(); switch (KeyBuffer[0]) { case 0x7f: /* here we got a delete */ KeyBuffer[0] = 0; if (collum == 0) conline[0] = 0; for(i=collum;i<254;i++) conline[i] = conline[i+1]; drawline(collum,TRUE); break; case 0x08: /* back space */ KeyBuffer[0] = 0; if (collum == 0) conline[0] = 0; if (collum > 0) { collum--; for(i=collum;i<254;i++) conline[i] = conline[i+1]; } drawline(collum, TRUE); break; case 0x0d: KeyBuffer[0] = 0; DoDOS(conline); /* This is the Biggie! */ if ( row == NLMO ) { if ( top + NUMLINES < numfiles ) { line++; scrprt(NUMLINES,++top); } else DisplayBeep(0L); } first = 0; collum = 0; for(i=0;i<255;i++) conline[i] = 0; break; case 0x9b: KeyBuffer[0] = 0; switch (KeyBuffer[1]) { case 0x3f: /* looking for the Help key */ if (KeyBuffer[2] == 0x7e) Help(); break; case 0x41: /* up arrow */ if (collum == 0) { for(i=0;i<255;i++) conline[i] = 0; } else { strcpy(buf,conline); conline[first] = 0; drawline(collum,TRUE); strcpy(conline,buf); } if (row > 0) { line--; row--; } else if (row == 0 && top > 0) { line--; scrprt(NUMLINES,--top); } drawline(collum,TRUE); break; case 0x42: /* Down Arrow */ if (collum == 0) { for(i=0;i<255;i++) conline[i] = 0; } else { strcpy(buf,conline); conline[first] = 0; drawline(collum,TRUE); strcpy(conline,buf); } if (row < NLMO) { if (line < numfiles - 1){ line++; row++; } } else if (row == NLMO && line < numfiles - 1) { line++; scrprt(NUMLINES,++top); } drawline(collum,TRUE); break; case 0x44: /* Left Arrow */ if (collum > 0) collum--; drawline(collum,TRUE); break; case 0x43: /* Right Arrow */ if (collum < 90) collum++; else DisplayBeep(NULL); drawline(collum,FALSE); break; default: check_for_shift(); break; } KeyBuffer[1] = 0; break; case 0x1b: /* The File name insertion thing... */ insert_name(); break; default: if (KeyBuffer[0] < 0x20) control_keys(KeyBuffer[0]); else enter_char(KeyBuffer[0]); break; } drawcur(); } } /* I split up the switch for two reasons... One, I though that the first was getting a bit big, Two, I think MANX chokes on large switches. */ /* Looking for the shift-arrow keys */ check_for_shift() { char buf[256]; switch (KeyBuffer[1]) { case 'T': if (top > 0) { if (line < 10) line = 0; else if (top < 10) line -= top; else line -= 10; if (top < 10) top = 0; else top -= 10; } scrprt(NUMLINES,top); strcpy(buf,conline); conline[first] = 0; drawline(collum,TRUE); strcpy(conline,buf); drawline(collum,TRUE); break; case 'S': if (numfiles - 11 > line) { if (numfiles - 11 < line) line = numfiles - 1; else line += 10; if (top+10 > numfiles - 1) top = numfiles - 1; else top += 10; } scrprt(NUMLINES,top); strcpy(buf,conline); conline[first] = 0; drawline(collum,TRUE); strcpy(conline,buf); drawline(collum,TRUE); break; case ' ': switch(KeyBuffer[2]) { case 'A': /* left arrow */ collum = 0; first = 0; drawline(collum,TRUE); break; case '@': /* right arrow */ collum = strlen(conline); first = collum > 29 ? collum - 29: 0; drawline(collum,TRUE); break; } } } control_keys(key) char key; { char buf[256]; int i; switch(key) { case 0x01: /* ^A - get the Arp file-requestor */ if (Wbargs() == 0){ UnLock(olddir); refresh(); } break; case 0x03: /* user typed ^C */ _abort(); break; case 0x04: /* ^D - change directory to fname */ /* ***** Hidden SECRET of AmigaDOS !! ***** only found in the RKM includes... You can tell if a file is really a file or if it is a directory by the value of DirEntryType. If it is < 0 then it is a file, if > 0 then it is a directory */ if (*finfo[line][0] < 0){ sprintf(buf,"%s Not a directory",fname[line]); auto_req(buf); }else { changedir(fname[line]); refresh(); } break; case 0x07: /* ^G - Re-get the current dir */ getdir(); refresh(); break; case 0x0b: /* ^K - Delete file */ kill(fname[line]); refresh(); break; case 0x0c: /* ^L - refresh the screen */ collum = 0; row = 0; line = 0; first = 0; top = 0; refresh(); /* also resets the cursor to zero pos */ break; case 0x0e: /* ^N - Make directory */ make_dir(); refresh(); break; case 0x0f: /* ^O - sort by pattern */ sort(3); refresh(); break; case 0x10: /* ^P - change directory to Parent */ parent(); refresh(); break; case 0x12: /* ^R - rename file */ rename_file(fname[line]); refresh(); break; case 0x13: /* ^S - sort by names */ sort(0); refresh(); break; case 0x14: /* ^T - sort by Time */ sort(2); refresh(); break; case 0x15: /* ^U - erase line to start */ for (i=0;i<254;i++) conline[i] = '\0'; first = 0; collum = 0; drawline(collum,TRUE); break; case 0x18: /* ^X - Start REXX macro */ dorexx(); break; case 0x19: /* ^Y - sort by day */ sort(4); refresh(); break; case 0x1a: /* ^Z - sort by size */ sort(1); refresh(); break; } } /* Enter a char into the array and screen */ enter_char(c) register char c; { int i; for(i=254;i>collum;i--) /* This is for insert mode */ conline[i] = conline[i-1]; KeyBuffer[0] = c; if (collum < 90) { conline[collum] = c; collum++; drawline(collum,FALSE); } else DisplayBeep(NULL); KeyBuffer[0] = 0; } /* Draw the current line from the cursor position, for scrolling */ drawline (curpos,flag) long curpos,flag; { long i,temp1,temp2; char tbuf[31]; #ifdef DEBUG char buf[90]; sprintf(buf," Row %ld Collumn %ld Top %ld First %ld line %ld \ numfiles %ld",row,collum,top,first,line,numfiles); SetWindowTitles(winptr,-1L,buf); #endif temp2 = LINEH * row + TOP + 2; if ((collum >= first+30) || (collum == first)) { if (flag){ if (first>0) first--; } else { if (first<89) first++; } } strncpy(tbuf,&conline[first],30); temp1 = strlen(tbuf); for(i=temp1;i<29;i++) tbuf[i] = ' '; tbuf[29] = '\0'; input.IText = tbuf; PrintIText(rp,&input,(LONG)LEFT,temp2); input.IText = KeyBuffer; } long getcol() { register long temp1; if (collum == first + 29) temp1 = CHARW * 29 + LEFT; else if (first == collum) temp1 = LEFT; else { temp1 = CHARW * (collum - first) + LEFT; } return temp1; } /* Draw the cursor at the current row & collum */ drawcur() { register long temp1,temp2; temp1 = getcol(); temp2 = LINEH * row + TOP + 2; SetDrMd(rp,COMPLEMENT|JAM1); SetAPen(rp,4); RectFill(rp,temp1,temp2,temp1+7,temp2+7); SetAPen(rp,2); SetDrMd(rp,JAM1); } /* Blank the cursur, where-ever it is. */ blankcur() { register long temp1,temp2; temp1 = getcol(); temp2 = LINEH * row + TOP + 2; SetDrMd(rp,COMPLEMENT|JAM2); SetAPen(rp,0); RectFill(rp,temp1,temp2,temp1+7,temp2+7); SetAPen(rp,2); SetDrMd(rp,JAM1); } /* This is where the File insertion code is (in case you were wondering) */ insert_name() { register int i, j; register char *temp; j=0; if(line > numfiles) return; for (i=collum;i<89;i++){ temp = fname[line]; if (temp[j] == 0) break; enter_char(temp[j++]); } } SHAR_EOF # End of shell archive exit 0 -- Bob Page, U of Lowell CS Dept. page@swan.ulowell.edu ulowell!page Have five nice days.