[comp.sources.amiga] v89i051: flist - scrollable cli and directory lister v1.2, Part03/03

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.