🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.sys.atari.st
Article #24788

Uemail source (9 of 12)

#24788
From: RDROYA01
Date: Thu, 05 Feb 1987 19:40
943 lines
32471 bytes
#       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:
#       shell.c
#       path.c
#       page.c
#       window.c
# This archive created: Tue Feb  3 18:08:00 1987
cat << \SHAR_EOF > shell.c
/* shell.c contains the routines to allow exec calls.  If there were a
 * small command interpreter somewhere, we could do a real spawn.
 * If you compile this to run from a shell, undefine GEMLOAD.  Since
 * shells eat memory, you can't give as much back to the OS.  If you
 * will be using this from GEM, give back 256K and you'll be able to
 * run just about any program from within the editor.
 */
 
#include "shell.h"
 
#ifdef  GEMLOAD
unsigned long _STKSIZ = -262144;        /* give back 256K to the OS */
#else
unsigned long _STKSIZ = -147456;        /* give back 144K to the OS */
#endif
 
char cline[MAXINPUT * 2];       /* holds the command line and other things */
char pnam[MAXINPUT+1];          /* program name */
char source[MAXINPUT+1];        /* name of file for aliasing */
char path[MAXPATH+1];           /* current path string  */
int delete = TRUE;              /* on/off for above     */
int dolink = 0;                 /* link a program       */
int temdrv;
int curdrv;
ALITAB *aheadp = NULL;          /* alias header */
 
shell(f, n)
register int f, n;
{
        extern char *alias(), *index(), *rindex();
        register char *ptr;
 
        if ((f=mlreply("!: ",cline,MAXINPUT))!=TRUE)
                return(f);
        if ((ptr=index(cline,' '))!=(char *)NULL)
                {
                *ptr = '\0';
                strcpy(pnam,cline);
                strcpy(&cline[1],++ptr);
                }
        else
                {
                strcpy(pnam,cline);
                strcpy(&cline[1]," ");
                }
        if (pnam[0] == '~')
                parsefn(pnam);
        if (alias(source,pnam)!=(char *)NULL)
                strcpy(pnam,source);
        /* check for file type (prg) and append if not there */
        if ((ptr=rindex(pnam,'\\'))!=(char *)NULL)      /* don't be fooled */
                {                                       /* by \foo.dir\bar */
                if (!index(ptr,'.'))
                        strcat(ptr,".prg");
                }
        else if (rindex(pnam,'.')==(char *)NULL)
                strcat(pnam,".prg");
        if (cline[1] == '~')
                parsefn(&cline[1]);
        while((ptr=index(&cline[1], '~'))!=(char *)NULL)
                if (!parsefn(ptr))
                        break;
        cline[0] = (char)strlen(&cline[1]);
        ttclose();      /* reset terminal characteristics */
        ttputc(0x1b); ttputc('E');
        Setexc(2,buserr);       /* use default exception handlers */
        Setexc(3,adderr);
        f = (int)Pexec(0,pnam,cline,0L);
        Setexc(2,&errexit);     /* reset local handlers */
        Setexc(3,&errexit);
        mtwrite("[Type a <CR>]");
        ttgetc();
        ttopen();       /* turn on uemail screen */
        if (f == FALSE && n == HUGE)    /* called from term */
                ;
        else
                {
                sgarbf = TRUE;  /* force full redraw */
                upmode();       /* set colors */
                update();       /* fix screen */
                }
        mlwrite("Return from %s = %d",pnam,f);
        return(TRUE);
}
 
/* read in the cc.ini file if it's on the default drive.  Called once at
 * editor startup and later by command.  Bound to CTRL-C.
 */
commfil(f,n)
register int f,n;
{
        FILE *fopen();
        register FILE *fp;
        char *fgets(),*index();
        char *ptr;
        static char line[MAXINPUT+1];
 
        /* for the call from main */
        if (f == FALSE && n == HUGE)
                {
                if ((fp=fopen("cc.ini","r")) == NULL)
                        {
                        Dgetpath(path,0);
                        mlwrite("Cannot open %s\\cc.ini",path);
                        return(FALSE);
                        }
                }
        else
                {
                if ((f=mlreply("Command file: ",line,MAXINPUT))!=TRUE)
                        return(f);
                if (line[0] == '~')
                        parsefn(line);
                if ((fp=fopen(line, "r"))==NULL)
                        {
                        mlwrite("Cannot open %s",line);
                        return(FALSE);
                        }
                }
        while (fgets(line,MAXINPUT,fp))
                {
                /* kill trailing whitespace */
                if ((ptr=index(line,'\n'))!=(char *)NULL)
                        *ptr = '\0';
                if ((ptr=index(line,' '))!=(char *)NULL)
                        *ptr = '\0';
                if ((ptr=index(line,'\t'))!=(char *)NULL)
                        *ptr = '\0';
                /* terminate alias and get address of path */
                if ((ptr=index(line,'='))!=(char *)NULL)
                        *ptr = '\0';
                else    /* improper line */
                        continue;
                ++ptr;  /* now equals &path[0] */
                /* test two cases that aren't easy in a switch */
                if (strcmp(line,"F10")==NULL)
                        {
                        bindkey((SPEC|'D'),ptr);
                        continue;
                        }
                if (strcmp(line,"NENTER")==NULL)
                        {
                        bindkey((SPEC|'r'),ptr);
                        continue;
                        }
                f = strlen(line);
                n = strlen(ptr);
                /* bind function keys */
                if (line[0] == 'F' && f == 2)
                        {
                        switch(line[1])
                                {
                                case '1':
                                        bindkey((SPEC|';'),ptr);
                                        break;
                                case '2':
                                        bindkey((SPEC|'<'),ptr);
                                        break;
                                case '3':
                                        bindkey((SPEC|'='),ptr);
                                        break;
                                case '4':
                                        bindkey((SPEC|'>'),ptr);
                                        break;
                                case '5':
                                        bindkey((SPEC|'?'),ptr);
                                        break;
                                case '6':
                                        bindkey((SPEC|'@'),ptr);
                                        break;
                                case '7':
                                        bindkey((SPEC|'A'),ptr);
                                        break;
                                case '8':
                                        bindkey((SPEC|'B'),ptr);
                                        break;
                                case '9':
                                        bindkey((SPEC|'C'),ptr);
                                        break;
                                default:
                                        break;
                                }
                        }
                /* or maybe a number pad key */
                else if (line[0] == 'N' && f == 2)
                        {
                        switch(line[1])
                                {
                                case '(':
                                        bindkey((SPEC|'c'),ptr);
                                        break;
                                case ')':
                                        bindkey((SPEC|'d'),ptr);
                                        break;
                                case '/':
                                        bindkey((SPEC|'e'),ptr);
                                        break;
                                case '*':
                                        bindkey((SPEC|'f'),ptr);
                                        break;
                                case '7':
                                        bindkey((SPEC|'g'),ptr);
                                        break;
                                case '8':
                                        bindkey((SPEC|'h'),ptr);
                                        break;
                                case '9':
                                        bindkey((SPEC|'i'),ptr);
                                        break;
                                case '-':
                                        bindkey((SPEC|'J'),ptr);
                                        break;
                                case '4':
                                        bindkey((SPEC|'j'),ptr);
                                        break;
                                case '5':
                                        bindkey((SPEC|'k'),ptr);
                                        break;
                                case '6':
                                        bindkey((SPEC|'l'),ptr);
                                        break;
                                case '+':
                                        bindkey((SPEC|'N'),ptr);
                                        break;
                                case '1':
                                        bindkey((SPEC|'m'),ptr);
                                        break;
                                case '2':
                                        bindkey((SPEC|'n'),ptr);
                                        break;
                                case '3':
                                        bindkey((SPEC|'o'),ptr);
                                        break;
                                case '.':
                                        bindkey((SPEC|'q'),ptr);
                                        break;
                                default:
                                        break;
                                }
                        }
                /* search for a match */
                /* check possible alias definitions */
                else if (insalias(line,ptr)==FALSE)
                                {
                                fclose(fp);
                                return(FALSE);
                                }
                else if (feof(fp))
                        break;
                }
        fclose(fp);
        return(TRUE);
}
 
insalias(al,pa)
register char *al;
register char *pa;
{
        register int f, n;
        register ALITAB *apt;
        register int found;
 
        found = FALSE;
 
        if (aheadp == NULL)
                {
                if ((aheadp=(ALITAB *)malloc(sizeof(ALITAB)))==NULL)
                        {
                        mlwrite("Cannot allocate %d bytes",sizeof(ALITAB));
                        return(FALSE);
                        }
                if ((aheadp->alias=malloc(5))==NULL)
                        {
                        mlwrite("Alias alloc failure");
                        return(FALSE);
                        }
                if ((aheadp->value=malloc(11))==NULL)
                        {
                        mlwrite("Alias alloc failure");
                        return(FALSE);
                        }
                strcpy(aheadp->alias,"home");
                strcpy(aheadp->value,"c:\\uemail\\");
                aheadp->a_forw = NULL;
                }
        n = strlen(pa);
        f = strlen(al);
        apt = aheadp;
        while (apt)
                {
                if (strcmp(apt->alias,al)==NULL)
                        {
                        free(apt->value);
                        if((apt->value=malloc(n+1))==NULL)
                                {
                                mlwrite("Alias alloc failure %s",pa);
                                return(FALSE);
                                }
                        strcpy(apt->value,pa);
                        found == TRUE;
                        }
                if (apt->a_forw)
                        apt=apt->a_forw;
                else
                        break;
                }
        if (found)
                return(TRUE);
        /* not already bound */
        if ((apt->a_forw=(ALITAB *)malloc(sizeof(ALITAB)))== NULL)
                {
                mlwrite("Cannot allocate %d bytes",sizeof(ALITAB));
                return(FALSE);
                }
        apt=apt->a_forw;
        apt->a_forw=NULL;
        if ((apt->alias=malloc(f+1))==NULL)
                {
                mlwrite("Alias alloc failure %s",al);
                return(FALSE);
                }
        if ((apt->value=malloc(n+1))==NULL)
                {
                mlwrite("Alias alloc failure %s",pa);
                return(FALSE);
                }
        strcpy(apt->alias,al);
        strcpy(apt->value,pa);
        return(TRUE);
}
SHAR_EOF
cat << \SHAR_EOF > path.c
/* PATH.C  commands that deal with paths are in here */
 
#include "shell.h"
 
/* SETPATH set the current path and default drive.  This is needed on the
 * ST for shell programs that expand wildcards incorrectly when given
 * a command line which requests a drive other than the default.  The
 * command also uses the aliases listed above.  Bound to CTLX-D.
 */
setpath(f, n)
int f, n;
{
        register char *ptr;
        extern char *index(),*alias();
        char template[MAXINPUT+1];
        char subdir[MAXINPUT+1];        /* handle multiple path */
 
        if (n == 0)
                {
                f = (int)Dgetdrv();
                Dgetpath(path,(f+1));
                mlwrite("Default drive: %c: Default path: %s",(f + 'A'),path);
                return(TRUE);
                }
        mlreply("New drive and path: ",template,MAXINPUT-1);
        if (template[0] == '~') /* use alias if possible */
                {
                if ((ptr=index(template,' '))!=(char *)NULL)
                        *ptr = '\0';
                if ((ptr=index(template,'\t'))!=(char *)NULL)
                        *ptr = '\0';
                if ((ptr=index(template,'\\'))!=(char *)NULL)
                        {
                        *ptr = '\0';
                        ++ptr;
                        strcpy(subdir,ptr);
                        n = 0;
                        }
                if (alias(&path[0],&template[1]) == (char *)NULL)
                        return(FALSE);
                if (n==0)
                        strcat(path,subdir);
                }
        else
                strcpy(path,template);
        if ((ptr=index(path,':'))!=(char *)NULL)
                {
                --ptr;
                f = (int)toupper(*ptr);
                if (f < 'A' || f > 'P')
                        {
                        mlwrite("Illegal drive specification %c:",f);
                        return(FALSE);
                        }
                f -= 'A';
                Dsetdrv(f);
                }
        Dsetpath(path);
        return(TRUE);
}
 
/* look up the string template in the known aliased names.  If it's a
 * known alias, copy the actual path into dirpath and return a pointer
 * to dirpath.  If it is not legit, complain and return NULL.  Called
 * by any command that looks at a file on disk.
 */
char *
alias(dirpath, template)
register char *dirpath;
register char *template;
{
        register ALITAB *apt;
 
        apt = aheadp;
        if (apt == NULL)
                {
                mlwrite("No aliases defined");
                return((char *)NULL);
                }
        while (apt)
                {
                if (strcmp(template,apt->alias)==NULL)
                        {
                        strncpy(dirpath,apt->value,MAXINPUT);
                        return(dirpath);
                        }
                apt=apt->a_forw;
                }
        return((char *)NULL);
}
SHAR_EOF
cat << \SHAR_EOF > page.c
#include <stdio.h>
#include "ed.h"
 
int pagelen = 60;       /* default page length */
 
/* PAGINATE : eXtended command  Set mark, goto beginning of file and move
 * beginning to end inserting formfeeds.  Bound to CTLX-!.
 */
 
paginate(f, n)
register int f, n;
{
        setmark(NULL, 1);
        gotobob(NULL, 1);
 
        while(pageforw(NULL, 1) != FALSE)
                {
                openline(NULL, 1);
                linsert(1 ,'\f');
                }
        return(swapmark(NULL, 1));
}
 
/* SETPAGE eXtended command  Set page length for paginate.  Or tell page
 * length already set.  Bound to CTLX-#.
 */
 
setpage(f ,n)
register int f, n;
{
 
        if (n > 1 && n < 100)
                pagelen = n;
 
        mlwrite ("Page length is %d", pagelen);
                return(TRUE);
}
 
/* PAGEFORW eXtended command  move forward by set page size.  Bound to
 * CTLX-+.
 */
 
pageforw(f, n)
register int f, n;
{
        register int c;
 
        c = 0;
 
        if (n < 0)
                return(pageback(f, -n));
        while(n)
                {
                if (curwp->w_dotp != curbp->b_linep)
                        {
                        forwline(NULL, 1);
                        ++c;
                        if (c == pagelen)
                                {
                                c = 0;
                                --n;
                                continue;
                                }
                        }
                else
                        return(FALSE);
                }
        return(TRUE);
}
 
/* PAGEBACK eXtended command  move forward by set page size.  Bound to
 * CTLX-+.
 */
 
pageback(f, n)
register int f, n;
{
        register int c;
 
        c = 0;
 
        if (n < 0)
                return(pageforw(f, -n));
        while(n)
                {
                if (lback(curwp->w_dotp) != curbp->b_linep)
                        {
                        backline(NULL, 1);
                        ++c;
                        if (c == pagelen)
                                {
                                c = 0;
                                --n;
                                continue;
                                }
                        }
                else
                        return(FALSE);
                }
        return(TRUE);
}
SHAR_EOF
cat << \SHAR_EOF > window.c
/*
 * Window management.
 * Some of the functions are internal,
 * and some are attached to keys that the
 * user actually types.
 */
#include        <stdio.h>
#include        "ed.h"
 
/*
 * Reposition dot in the current
 * window to line "n". If the argument is
 * positive, it is that line. If it is negative it
 * is that line from the bottom. If it is 0 the window
 * is centered (this is what the standard redisplay code
 * does). With no argument it defaults to 1. Bound to
 * M-!. Because of the default, it works like in
 * Gosling.
 */
reposition(f, n)
register int f, n;
{
        curwp->w_force = n;
        curwp->w_flag |= WFFORCE;
        return (TRUE);
}
 
/*
 * Refresh the screen. With no
 * argument, it just does the refresh. With an
 * argument it recenters "." in the current
 * window. Bound to "C-L".
 */
refresh(f, n)
register int f, n;
{
        if (f == FALSE)
                sgarbf = TRUE;
        else {
                curwp->w_force = 0;             /* Center dot.          */
                curwp->w_flag |= WFFORCE;
        }
        return (TRUE);
}
 
/*
 * The command make the next
 * window (next => down the screen)
 * the current window. There are no real
 * errors, although the command does
 * nothing if there is only 1 window on
 * the screen. Bound to "C-X C-N".
 */
nextwind(f, n)
register int f, n;
{
        register WINDOW *wp;
        register WINDOW *wp2;
 
        if ((wp=curwp->w_wndp) == NULL)
                wp = wheadp;
        curwp = wp;
        curbp = wp->w_bufp;
        upmode();
        return (TRUE);
}
 
/*
 * This command makes the previous
 * window (previous => up the screen) the
 * current window. There arn't any errors,
 * although the command does not do a lot
 * if there is 1 window.
 */
prevwind(f, n)
register int f, n;
{
        register WINDOW *wp1;
        register WINDOW *wp2;
 
        wp1 = wheadp;
        wp2 = curwp;
        if (wp1 == wp2)
                wp2 = NULL;
        while (wp1->w_wndp != wp2)
                wp1 = wp1->w_wndp;
        curwp = wp1;
        curbp = wp1->w_bufp;
        upmode();
        return (TRUE);
}
 
/*
 * This command moves the current
 * window down by "arg" lines. Recompute
 * the top line in the window. The move up and
 * move down code is almost completely the same;
 * most of the work has to do with reframing the
 * window, and picking a new dot. We share the
 * code by having "move down" just be an interface
 * to "move up". Magic. Bound to "C-X C-N".
 */
mvdnwind(f, n)
register int    f, n;
{
        return (mvupwind(f, -n));
}
 
/*
 * Move the current window up by "arg"
 * lines. Recompute the new top line of the window.
 * Look to see if "." is still on the screen. If it is,
 * you win. If it isn't, then move "." to center it
 * in the new framing of the window (this command does
 * not really move "."; it moves the frame). Bound
 * to "C-X C-P".
 */
mvupwind(f, n)
register int    f, n;
{
        register LINE   *lp;
        register int    i;
 
        lp = curwp->w_linep;
        if (n < 0) {
                while (n++ && lp!=curbp->b_linep)
                        lp = lforw(lp);
        } else {
                while (n-- && lback(lp)!=curbp->b_linep)
                        lp = lback(lp);
        }
        curwp->w_linep = lp;
        curwp->w_flag |= WFHARD;                /* Mode line is OK.     */
        for (i=0; i<curwp->w_ntrows; ++i) {
                if (lp == curwp->w_dotp)
                        return (TRUE);
                if (lp == curbp->b_linep)
                        break;
                lp = lforw(lp);
        }
        lp = curwp->w_linep;
        i  = curwp->w_ntrows/2;
        while (i-- && lp!=curbp->b_linep)
                lp = lforw(lp);
        curwp->w_dotp  = lp;
        curwp->w_doto  = 0;
        return (TRUE);
}
 
/*
 * This command makes the current
 * window the only window on the screen.
 * Bound to "C-X 1". Try to set the framing
 * so that "." does not have to move on
 * the display. Some care has to be taken
 * to keep the values of dot and mark
 * in the buffer structures right if the
 * distruction of a window makes a buffer
 * become undisplayed.
 */
onlywind(f, n)
register int f, n;
{
        register WINDOW *wp;
        register LINE   *lp;
        register int    i;
 
        while (wheadp != curwp) {
                wp = wheadp;
                wheadp = wp->w_wndp;
                if (--wp->w_bufp->b_nwnd == 0) {
                        wp->w_bufp->b_dotp  = wp->w_dotp;
                        wp->w_bufp->b_doto  = wp->w_doto;
                        wp->w_bufp->b_markp = wp->w_markp;
                        wp->w_bufp->b_marko = wp->w_marko;
                }
                free((char *) wp);
        }
        while (curwp->w_wndp != NULL) {
                wp = curwp->w_wndp;
                curwp->w_wndp = wp->w_wndp;
                if (--wp->w_bufp->b_nwnd == 0) {
                        wp->w_bufp->b_dotp  = wp->w_dotp;
                        wp->w_bufp->b_doto  = wp->w_doto;
                        wp->w_bufp->b_markp = wp->w_markp;
                        wp->w_bufp->b_marko = wp->w_marko;
                }
                free((char *) wp);
        }
        lp = curwp->w_linep;
        i  = curwp->w_toprow;
        while (i!=0 && lback(lp)!=curbp->b_linep) {
                --i;
                lp = lback(lp);
        }
        curwp->w_toprow = 0;
        curwp->w_ntrows = term.t_nrow-1;
        curwp->w_linep  = lp;
        curwp->w_flag  |= WFMODE|WFHARD;
        return (TRUE);
}
 
/*
 * Split the current window. A window
 * smaller than 3 lines cannot be split.
 * The only other error that is possible is
 * a "malloc" failure allocating the structure
 * for the new window. Bound to "C-X 2".
 */
splitwind(f, n)
register int f, n;
{
        register WINDOW *wp;
        register LINE   *lp;
        register int    ntru;
        register int    ntrl;
        register int    ntrd;
        register WINDOW *wp1;
        register WINDOW *wp2;
 
        if (curwp->w_ntrows < 3) {
                mlwrite("Cannot split a %d line window", curwp->w_ntrows);
                return (FALSE);
        }
        if ((wp = (WINDOW *) malloc(sizeof(WINDOW))) == NULL) {
                mlwrite("Cannot allocate WINDOW block");
                return (FALSE);
        }
        ++curbp->b_nwnd;                        /* Displayed twice.     */
        wp->w_bufp  = curbp;
        wp->w_dotp  = curwp->w_dotp;
        wp->w_doto  = curwp->w_doto;
        wp->w_markp = curwp->w_markp;
        wp->w_marko = curwp->w_marko;
        wp->w_flag  = 0;
        wp->w_force = 0;
        ntru = (curwp->w_ntrows-1) / 2;         /* Upper size           */
        ntrl = (curwp->w_ntrows-1) - ntru;      /* Lower size           */
        lp = curwp->w_linep;
        ntrd = 0;
        while (lp != curwp->w_dotp) {
                ++ntrd;
                lp = lforw(lp);
        }
        lp = curwp->w_linep;
        if (ntrd <= ntru) {                     /* Old is upper window. */
                if (ntrd == ntru)               /* Hit mode line.       */
                        lp = lforw(lp);
                curwp->w_ntrows = ntru;
                wp->w_wndp = curwp->w_wndp;
                curwp->w_wndp = wp;
                wp->w_toprow = curwp->w_toprow+ntru+1;
                wp->w_ntrows = ntrl;
        } else {                                /* Old is lower window  */
                wp1 = NULL;
                wp2 = wheadp;
                while (wp2 != curwp) {
                        wp1 = wp2;
                        wp2 = wp2->w_wndp;
                }
                if (wp1 == NULL)
                        wheadp = wp;
                else
                        wp1->w_wndp = wp;
                wp->w_wndp   = curwp;
                wp->w_toprow = curwp->w_toprow;
                wp->w_ntrows = ntru;
                ++ntru;                         /* Mode line.           */
                curwp->w_toprow += ntru;
                curwp->w_ntrows  = ntrl;
                while (ntru--)
                        lp = lforw(lp);
        }
        curwp->w_linep = lp;                    /* Adjust the top lines */
        wp->w_linep = lp;                       /* if necessary.        */
        curwp->w_flag |= WFMODE|WFHARD;
        wp->w_flag |= WFMODE|WFHARD;
        return (TRUE);
}
 
/*
 * Enlarge the current window.
 * Find the window that loses space. Make
 * sure it is big enough. If so, hack the window
 * descriptions, and ask redisplay to do all the
 * hard work. You don't just set "force reframe"
 * because dot would move. Bound to "C-X Z".
 */
enlargewind(f, n)
register int f, n;
{
        register WINDOW *adjwp;
        register LINE   *lp;
        register int    i;
 
        if (n < 0)
                return (shrinkwind(f, -n));
        if (wheadp->w_wndp == NULL) {
                mlwrite("Only one window");
                return (FALSE);
        }
        if ((adjwp=curwp->w_wndp) == NULL) {
                adjwp = wheadp;
                while (adjwp->w_wndp != curwp)
                        adjwp = adjwp->w_wndp;
        }
        if (adjwp->w_ntrows <= n) {
                mlwrite("Impossible change");
                return (FALSE);
        }
        if (curwp->w_wndp == adjwp) {           /* Shrink below.        */
                lp = adjwp->w_linep;
                for (i=0; i<n && lp!=adjwp->w_bufp->b_linep; ++i)
                        lp = lforw(lp);
                adjwp->w_linep  = lp;
                adjwp->w_toprow += n;
        } else {                                /* Shrink above.        */
                lp = curwp->w_linep;
                for (i=0; i<n && lback(lp)!=curbp->b_linep; ++i)
                        lp = lback(lp);
                curwp->w_linep  = lp;
                curwp->w_toprow -= n;
        }
        curwp->w_ntrows += n;
        adjwp->w_ntrows -= n;
        curwp->w_flag |= WFMODE|WFHARD;
        adjwp->w_flag |= WFMODE|WFHARD;
        return (TRUE);
}
 
/*
 * Shrink the current window.
 * Find the window that gains space. Hack at
 * the window descriptions. Ask the redisplay to
 * do all the hard work. Bound to "C-X C-Z".
 */
shrinkwind(f, n)
register int f, n;
{
        register WINDOW *adjwp;
        register LINE   *lp;
        register int    i;
 
        if (n < 0)
                return (enlargewind(f, -n));
        if (wheadp->w_wndp == NULL) {
                mlwrite("Only one window");
                return (FALSE);
        }
        if ((adjwp=curwp->w_wndp) == NULL) {
                adjwp = wheadp;
                while (adjwp->w_wndp != curwp)
                        adjwp = adjwp->w_wndp;
        }
        if (curwp->w_ntrows <= n) {
                mlwrite("Impossible change");
                return (FALSE);
        }
        if (curwp->w_wndp == adjwp) {           /* Grow below.          */
                lp = adjwp->w_linep;
                for (i=0; i<n && lback(lp)!=adjwp->w_bufp->b_linep; ++i)
                        lp = lback(lp);
                adjwp->w_linep  = lp;
                adjwp->w_toprow -= n;
        } else {                                /* Grow above.          */
                lp = curwp->w_linep;
                for (i=0; i<n && lp!=curbp->b_linep; ++i)
                        lp = lforw(lp);
                curwp->w_linep  = lp;
                curwp->w_toprow += n;
        }
        curwp->w_ntrows -= n;
        adjwp->w_ntrows += n;
        curwp->w_flag |= WFMODE|WFHARD;
        adjwp->w_flag |= WFMODE|WFHARD;
        return (TRUE);
}
 
/*
 * Pick a window for a pop-up.
 * Split the screen if there is only
 * one window. Pick the uppermost window that
 * isn't the current window. An LRU algorithm
 * might be better. Return a pointer, or
 * NULL on error.
 */
WINDOW  *
wpopup()
{
        register WINDOW *wp;
 
        if (wheadp->w_wndp == NULL              /* Only 1 window        */
        && splitwind(FALSE, 0) == FALSE)        /* and it won't split   */
                return (NULL);
        wp = wheadp;                            /* Find window to use   */
        while (wp!=NULL && wp==curwp)
                wp = wp->w_wndp;
        return (wp);
}
SHAR_EOF
#       End of shell archive
exit 0
%NONAME-W-NOMSG, Message number 00000000
Technical Details
Message-ID: <8702060152.AA20089@ucbvax.Berkeley.EDU>
Path: arc1-ca.pugleaf.net!utzoo!watmath!clyde!rutgers!ames!ucbcad!ucbvax!ULKYVX.BITNET!RDROYA01

Show Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: arc1-ca.pugleaf.net!utzoo!watmath!clyde!rutgers!ames!ucbcad!ucbvax!ULKYVX.BITNET!RDROYA01
From: RDROYA01@ULKYVX.BITNET.UUCP
Newsgroups: comp.sys.atari.st
Subject: Uemail source (9 of 12)
Message-ID: <8702060152.AA20089@ucbvax.Berkeley.EDU>
Date: Thu, 5-Feb-87 14:40:00 EST
Article-I.D.: ucbvax.8702060152.AA20089
Posted: Thu Feb  5 14:40:00 1987
Date-Received: Sat, 7-Feb-87 16:30:47 EST
Sender: daemon@ucbvax.BERKELEY.EDU
Organization: University of Louisville
Lines: 943