home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GRIPS 2: Government Rast…rocessing Software & Data
/
GRIPS_2.cdr
/
dos
/
ncsa_tel
/
contribu
/
byu_tel2.hqx
/
vs
/
vsinterf.c
< prev
next >
Wrap
Text File
|
1990-05-03
|
23KB
|
1,002 lines
#ifdef lint
static char *SCCSid = "%W% (NCSA) %G%";
#endif
/*
*
* Virtual Screen Kernel Interface
* (vsinterf.c)
*
* by Gaige B. Paulsen
*
* This file contains the control and interface calls for the NCSA
* Virtual Screen Kernal.
*
* VSinit(maxwidth) - Initialize the VSK
* VSnewscreen(maxlines,scrnsave) - Initialize a new screen.
* VSdetatch(w) - Detach screen w
* VSredraw(w,x1,y1,x2,y2) - redraw region for window w
* VSwrite(w,ptr,len) - write text @ptr, length len
* VSclear(w) - clear w's real screen
* VSkbsend(w,k,echo) - send keycode k's rep. out window w (w/echo if req.)
* VSclearall(w) - clear w's real and saved screen
* VSreset(w) - reset w's emulator (as per TERM)
* VSgetline(w,y) - get a ptr to w's line y
* VSsetrgn(w,x1,y1,x2,y2) - set local display region
* VSscrolback(w,n) - scrolls window w back n lines
* VSscrolforward(w,n) - scrolls window w forward n lines
* VSscrolleft(w,n) - scrolls window w left n columns
* VSscrolright(w,n) - scrolls window w right n columns
* VSscrolcontrol(w,scrlon,offtop) - sets scroll vars for w
* VSgetrgn(w,&x1,&y1,&x2,&y2) - returns set region
* VSsnapshot(w) - takes a snapshot of w
* VSgetlines(w) - Returns current # of lines
* VSsetlines(w, lines) - Sets the current # of lines to lines
*
* Version Date Notes
* ------- ------ ---------------------------------------------------
* 0.01 861102 Initial coding -GBP
* 0.10 861113 Added some actual program to this file -GBP
* 0.15 861114 Initiated Kludge Operation-GBP
* 0.50 8611VSPBOTTOM Parameters added to VSnewscreen -GBP
* 0.90 870203 Added the kbsend routine -GBP
* 2.1 871130 NCSA Telnet 2.1 -GBP
* 2.2 880715 NCSA Telnet 2.2 -GBP
*
*/
#define VSMASTER
#include "vsdata.h"
#include "vskeys.h"
#include "vsinit.h"
#define DEBUGMAC
#ifdef DEBUGMAC
pascal void DEBUGGER() extern 0xa9ff;
#endif DEBUGMAC
int VSmax=0,VSinuse=0; /* Internal variables for use in managing windows */
VSscrndata *VSscreens;
int VSinit(max)
int max;
{
int i;
RSinitall();
VSmax=max;
VSIwn=0;
if((VSscreens=(VSscrndata *)malloc(max*sizeof(VSscrndata)))==0L) return(-2);
for(i=0;i<max;i++) {
VSscreens[i].loc=0L;
VSscreens[i].stat=0;
}
return(0);
}
VSscrn *VSwhereis(i)
int i;
{
VSvalids(i);
return(VSIw);
}
int VSnewscreen(maxlines,screensave,maxwid,IDC)
int maxwid,maxlines,screensave,IDC;
{
int i,j;
VSline *tt,*last,*VSInewlines();
char *ta,*tx;
if (maxlines< VSDEFLINES) maxlines=VSDEFLINES;
if (VSinuse>=VSmax) return(-1);
VSIwn=0;
while((VSIwn<VSmax) &&(VSscreens[VSIwn].stat==1)) VSIwn++;
if (VSIwn>=VSmax) return(-1);
if (VSscreens[VSIwn].stat==2) {
VSIw=VSscreens[VSIwn].loc;
if (VSIw==0L) return(-7);
}
else
if ((VSscreens[VSIwn].loc=VSIw=(VSscrn *)malloc(sizeof(VSscrn)))==0L) {
VSscreens[VSIwn].loc=0L;
return(-2);
}
if ( VSscreens[VSIwn].stat !=2 ) {
VSIw->maxlines=maxlines;
VSIw->numlines=1;
}
VSIw->maxwidth=maxwid-1;
VSIw->allwidth=maxwid-1;
VSIw->savelines=screensave;
VSIw->attrib=0;
VSIw->Pattrib=-1;
VSIw->x=0;
VSIw->y=0;
VSIw->charset=0;
VSIw->G0=0;
VSIw->G1=1;
VSIw->VSIDC=IDC;
VSIw->DECAWM=0;
VSIw->DECCKM=0;
VSIw->DECPAM=0;
VSIw->DECORG=0;
VSIw->IRM=0;
VSIw->escflg=0;
VSIw->top=0;
VSIw->bottom=23; /* BYU mod */
VSIw->parmptr=0;
VSIw->Rtop=0;
VSIw->Rleft=0;
VSIw->Rright=79;
VSIw->Rbottom=23; /* BYU mod */
VSIw->ESscroll=1;
VSIw->lines = 23; /* BYU mod */
VSIw->linest = (VSline **) malloc( sizeof( VSline *) * (VSIw->lines+1));
VSIw->attrst = (VSline **) malloc( sizeof( VSline *) * (VSIw->lines+1));
VSinuse++;
if (VSscreens[VSIwn].stat==2) {
VSscreens[VSIwn].stat=1;
VSIclrbuf();
VSItabinit();
return(VSIwn);
}
VSscreens[VSIwn].stat=1;
VSIw->tabs = (char *)malloc(maxwid);
/*
* Fill initial scrollback buffer and screen storage space.
*
* Memory allocation rules:
* line->mem == 0 if not a memory allocation, line->mem == 1 if it is the first
* VSline in a block (indeterminate size, may be size == 1)
*
* attributes array is ALWAYS allocated as one block. Internally represented and
* manipulated as a linked list of lines, but only one of the lines will have
* line->mem == 1. This list is always supposed to be circular.
*
* scrollback and screen line buffer space is allocated in large blocks. Each
* block will have line->mem == 1 if the pointer to that VSline is "free"able.
* This list will either be circular (full size), or it will have a NULL next
* field at the end. During scrolling, the end may be augmented until
* VSIw->numlines > VSIw->maxlines or we run out of memory. Typically allocate
* memory 100 lines at a time in two blocks, one is the VSline list, the other
* is the mem for the character storage.
*
*/
tt = VSInewlines(VSPBOTTOM+VSDEFLINES+2); /* new space, already linked up */
if (!tt)
return(-2);
VSIw->buftop = tt;
for(i=0; i<= (VSPBOTTOM+1); i++) {
tx= tt->text;
for(j=0; j<=VSIw->allwidth;j++) *tx++=' '; /* Clear out the blumin' line */
tt = tt->next;
}
VSIw->scrntop= VSIw->buftop->next;
tt = VSInewlines(VSPBOTTOM+1); /* new space for attributes */
if (!tt)
return(-2);
VSIw->attrst[0]=tt;
VSIlistndx(VSIw->scrntop, VSIw->attrst[0]); /* Assign lists */
VSIw->attrst[ 0]->prev= VSIw->attrst[VSPBOTTOM]; /* Make attr circ. */
VSIw->attrst[VSPBOTTOM]->next= VSIw->attrst[ 0];
VSIclrbuf();
VSItabinit();
VSIw->vistop=VSIw->scrntop;
#ifdef DEBUGPC
VSckconsist( 1,1);
#endif DEBUGPC
return(VSIwn);
}
VSdestroy(w)
int w;
{
VSline *p,*oldp;
if (VSvalids(w)!=0) return(-3);
p=VSIw->attrst[0];
do {
if (p->mem) {
free(p->text);
free(p);
break;
}
p=p->next;
} while ( (p!=0L) && (p!=VSIw->attrst[ 0 ]) );
VSIfreelines(); /* free mem associated with scrollback lines */
free( VSIw->tabs);
free( VSIw);
VSscreens[w].stat=0;
VSIwn = -1;
VSinuse--; /* SCA '87 */
return(0);
}
#ifdef DEBUGPC
int VSckconsist(out,verbose)
int out,verbose;
{
VSline *topa,*topt,*a,*t;
int line, i;
for (i=0; i<VSmax; i++) { /* For all possible screens... */
switch( VSscreens[i].stat) {
case 0:
if (out && verbose) printf("Screen %d inactive\n",i);
break;
case 1:
if (out) printf("Screen %d active\n",i);
VSvalids(i);
topa=VSIw->attrst[ 0]->prev; topt=VSIw->linest[ 0]->prev;
a = VSIw->attrst[0]->next; t= VSIw->linest[0]->next;
if (topa && out) printf(" Attrib thinks its circular\n");
if (topa != VSIw->attrst[VSPBOTTOM])
printf("***********BUT IT'S NOT*************\n");
for (line=1; line<=VSPBOTTOM; line++) {
if (a != VSIw->attrst[ line]) {
if (out) printf(" Attrib line %d is wrong !\n", line);
else return(-1);
}
a = a->next;
if ( !a) {
if (out) printf(" Attrib line %d is NULL\n", line);
else if (!out && line!=VSPBOTTOM) return(-2);
}
}
if (topt && out) printf(" Linest thinks its circular\n");
if (VSIw->linest[VSPBOTTOM]->next) printf(" More than VSPBOTTOM lines.... \n");
for (line=1; line<=VSPBOTTOM; line++) {
if (t != VSIw->linest[ line]) {
if (out) printf(" Linest line %d is wrong !\n", line);
else return (-3);
}
t = t->next;
if ( !t) {
if (out) printf(" Linest line %d is NULL\n", line);
else if (line!=VSPBOTTOM) return(-4);
}
}
if (VSIw->numlines >0) {
if (out)
printf(" Thinks that there is scrollback of %d lines ", VSIw->numlines);
t= VSIw->linest[VSPBOTTOM]->next;
line=0;
while ( t!=0L && t!=VSIw->buftop) {
t=t->next;
line++;
}
if (out) printf(" [ Actual is %d ]\n", line);
if (out && t==0L) printf(" Lines end in a null\n");
if (out && t==VSIw->buftop) printf(" Lines end in a wraparound\n");
}
else if (out) printf(" There is no scrollback");
break;
case 2:
if (out && verbose) printf("Screen %d detached\n",i);
break;
default:
if (out) printf("Screen %d invalid stat\n",i);
break;
}
}
return(0);
}
#endif DEBUGPC
#ifdef USEDETATCH
VSdetatch(w)
int w;
{
if (VSscreens[w].stat!=1) return(-1);
VSscreens[w].stat=2;
VSIwn = -1;
VSinuse--; /* SCA '87 */
}
#else
VSdetatch(w)
int w;
{
VSdestroy(w);
}
#endif
VSIclrbuf()
{
register int j,i;
register char *ta,*tx;
for(i=0; i<=VSPBOTTOM; i++) {
ta = &VSIw->attrst[i]->text[0];
tx = &VSIw->linest[i]->text[0];
for(j=0; j<=VSIw->allwidth;j++) {
*ta++=0;
*tx++=' ';
}
}
}
VSredraw(w,x1,y1,x2,y2)
int w,x1,y1,x2,y2;
{
char *pt,*pa;
int cc,cm;
char lc,la;
register VSline *yp;
register int y;
int ox,tx1,tx2,ty1,ty2, tn = -1,offset;
if (VSvalids(w)!=0) return(-3);
VSIcuroff(w);
x1+= VSIw->Rleft; x2+=VSIw->Rleft; /* Make local coords global again */
y1+= VSIw->Rtop; y2+=VSIw->Rtop;
if (x2<0) x2=0;
if (x1<0) x1=0;
if (x2>VSIw->maxwidth) x2=VSIw->maxwidth;
if (x1>VSIw->maxwidth) x1=VSIw->maxwidth;
if (y2<-VSIw->numlines) y2= -VSIw->numlines; /* compare to amount of scrollback */
if (y1<-VSIw->numlines) y1= -VSIw->numlines;
if (y2>VSPBOTTOM) y2=VSPBOTTOM;
if (y1>VSPBOTTOM) y1=VSPBOTTOM;
tx1=x1; tx2=x2; ty1=y1; ty2=y2; /* Set up VSIclip call */
if (!VSIclip (&tx1,&ty1,&tx2,&ty2, &tn, &offset) )
RSerase(w,tx1,ty1,tx2,ty2); /* Erase the offending area */
if ( y1 <0) {
yp = VSIw->vistop;
y= y1 - VSIw->Rtop;
while ( y-- >0) yp=yp->next; /* Get pointer to top line we need */
}
y=y1;
while ( (y<0) && ( y<=y2) ) {
ox=tx1=x1; tx2=x2; ty1=ty2=y; tn = -1;
if ( !VSIclip( &tx1,&ty1, &tx2, &ty2, &tn, &offset) )
RSdraw( w, tx1,ty1,0,tn, &yp->text[ox+offset]);
yp=yp->next;
y++;
}
while ( y<= y2) {
pt= &VSIw->linest[y]->text[x2];
pa= &VSIw->attrst[y]->text[x2];
cm=x2; cc=1;
lc = *pt; la = *pa;
while (cm >=x1) {
if ((lc==' ') &&(la==0)) {
while( (cm>x1) && (*(pt-1)==' ') && (*(pa-1)==0) ) {
pa--;pt--;cm--;cc++;}
pa--;pt--;
cm--;cc=1;
lc= *pt; la= *pa;
continue;
}
while( (cm>x1) && (la==*(pa-1)) ) {pa--;pt--;cm--;cc++;}
if (cm>=x1) VSIdraw(w,cm,y,la,cc,pt);
pa--;pt--;
cm--;cc=1;
lc= *pt;la= *pa;
}
y++;
}
VSIcurson(w,VSIw->x,VSIw->y, 0); /* Don't force move */
tx1=ty1=0; tn=132;
if (!VSIclip( &tx1, &ty1,&tx2,&ty2, &tn, &offset) )
RSdrawsep( w, ty1, 1); /* Draw Separator */
return(0);
}
VSwrite(w,ptr,len)
int w,len;
char *ptr;
{
if (VSvalids(w)!=0) return(-3);
VSIcuroff(w);
VSem(ptr,len);
VSIcurson(w,VSIw->x,VSIw->y, 1); /* Force Move */
return(0);
}
VSclear(w)
int w;
{
if (VSvalids(w)!=0) return(-3);
VSIes();
VSIw->x=VSIw->y=0;
VSIcurson(w,VSIw->x,VSIw->y, 1); /* Force Move */
return(0);
}
VSpossend(w,x,y,echo)
int w,x,y,echo;
{
static char VSkbax[]="\033O ", /* prefix for auxiliary code*/
VSkban[]="\033[ "; /* prefix for arrows normal */
char *vskptr;
if (VSvalids(w)!=0) return(-3);
if (VSIw->DECPAM && VSIw->DECCKM)
vskptr = VSkbax;
else
vskptr = VSkban;
if (x<0 ||y<0 ||x>VSIw->maxwidth ||y>VSPBOTTOM) return(-10);
x -= VSIw->x;
y -= VSIw->y;
vskptr[2]='B';
while( y>0)
{ y--; RSsendstring(w,vskptr,3); }
vskptr[2]='A';
while( y<0)
{ y++; RSsendstring(w,vskptr,3); }
vskptr[2]='C';
while( x>0)
{ x--; RSsendstring(w,vskptr,3); }
vskptr[2]='D';
while( x<0)
{ x++; RSsendstring(w,vskptr,3); }
if (echo) {
VSIcuroff(w);
VSIw->x = x;
VSIw->y = y;
VSIcurson(w,VSIw->x,VSIw->y, 1); /* Force Move */
}
}
char VSkbsend(w,k, echo)
int w, echo;
unsigned char k;
{
static char VSkbkn[]="\033O ", /* prefix for keypad normal */
VSkbax[]="\033O ", /* prefix for auxiliary code*/
VSkban[]="\033[ ", /* prefix for arrows normal */
VSkbfn[]="\033O" ; /* prefix for function keys */
char *vskptr;
int vskplen;
if (VSvalids(w)!=0) return(-3);
if (k<VSUP) RSsendstring(w,&k,1);
if ((k>VSLT) && (k<VSF1) && (!VSIw->DECPAM)) {
RSsendstring(w,&VSIkpxlate[0][k-VSUP],1);
if (echo)
VSwrite(w,&VSIkpxlate[0][k-VSUP],1);
if (k==VSKE) RSsendstring(w,"\012",1);
return(0);
}
if (VSIw->DECPAM && VSIw->DECCKM)
{ vskptr= VSkbax; vskplen=3; } /* aux kp mode */
else if (k<VSK0) { vskptr= VSkban; vskplen=3; }
else if (k<VSF1) { vskptr= VSkbkn; vskplen=3; }
else { vskptr= VSkbfn; vskplen=3; }
vskptr[vskplen-1]=VSIkpxlate[1][k-VSUP];
RSsendstring(w,vskptr,vskplen);
if (echo)
VSwrite(w,vskptr,vskplen);
return(0);
}
VSclearall(w)
int w;
{
if (VSvalids(w)!=0) return(-3);
return(0);
}
VSreset(w)
int w;
{
if (VSvalids(w)!=0) return(-3);
VSIreset();
VSIcurson(w,VSIw->x,VSIw->y, 1); /* Force Move */
return(0);
}
char *VSgetline(w,y)
int w,y;
{
if (VSvalids(w)!=0) return( (char *) -3);
return(VSIw->linest[y]->text);
/* Need to add code for scrolled back lines */
}
VSsetrgn(w,x1,y1,x2,y2)
int w,x1,y1,x2,y2;
{
int n,offset;
if (VSvalids(w)!=0) return(-3);
VSIw->Rbottom = VSIw->Rtop +(y2-y1); /* Reduce window size first */
if ( x2> VSIw->maxwidth ) {
n=x2-VSIw->maxwidth; /* Get the maximum width */
if ( (x1-n) <0) n=x1; /* never a pos. offset from the left */
x1 -= n; /* Adjust left */
x2 -= n; /* Adjust right */
}
if ( VSIw->Rleft !=x1 ) { /* If the left margin changes then do scroll immediately */
n = x1 -VSIw->Rleft; /* Because LM change, TM change and Size change are the */
if (n >0) VSscrolright( w,n); /* Only valid ways to call this proc */
else VSscrolleft(w, -n);
}
else RSmargininfo( w, VSIw->maxwidth- (x2-x1), x1);
VSIw->Rleft= x1; /* Same with the margins */
VSIw->Rright = x2;
if (VSIw->Rbottom>VSPBOTTOM) {
n=VSIw->Rbottom-VSPBOTTOM;
}
else n = VSIw->Rtop -y1;
if ( n > 0) VSscrolback(w,n); /* Go forward */
else {
if (n <0) VSscrolforward(w,-n); /* And backward on command */
else {
x1=y1=1;n=132;
if (!VSIclip( &x1, &y1,&x2,&y2, &n, &offset) )
RSdrawsep( w, n,1); /* Draw Separator */
RSbufinfo( w, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom);
}
}
return(0);
}
VSscrolback(w,in)
int w,in;
{
int sn,x1,y1,x2,y2,n;
n=in;
if (VSvalids(w)!=0) return(-3);
if (VSIw->numlines < (n-VSIw->Rtop) ) /* Check against bounds */
n= VSIw->Rtop+VSIw->numlines;
if (n<=0) return(0); /* Dont be scrollin' no lines.... */
VSIcuroff(w);
VSIw->Rtop= VSIw->Rtop-n; /* Make the new region */
VSIw->Rbottom=VSIw->Rbottom-n;
sn=n;
while (sn-->0) {
#ifdef DEBUGMAC
if (VSIw->vistop->prev == 0L) DEBUGGER();
#endif DEBUGMAC
VSIw->vistop=VSIw->vistop->prev;
}
sn=VSIw->Rbottom-VSIw->Rtop;
RSbufinfo( w, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom);
if (n<=VSPBOTTOM) {
RSinslines(w,0,sn,n, 0); /* Dont be destructive */
VSIcurson(w,VSIw->x, VSIw->y, 0); /* Dont force move */
VSredraw(w,0,0,VSIw->maxwidth,n-1);
}
else
VSredraw(w,0,0,VSIw->maxwidth,sn);
return(0);
}
VSscrolforward(w,n)
int w,n;
{
int sn,x1,y1,x2,y2;
if (VSvalids(w)!=0) return(-3);
if ( VSIw->Rtop+n > (VSPBOTTOM-(VSIw->Rbottom - VSIw->Rtop))) /* Check against bounds */
n= VSPBOTTOM-(VSIw->Rbottom - VSIw->Rtop) -VSIw->Rtop;
if (n<=0) return(0); /* Dont be scrollin' no lines.... */
VSIcuroff(w);
VSIw->Rtop= n+VSIw->Rtop; /* Make the new region */
VSIw->Rbottom=n+VSIw->Rbottom;
sn=n;
while (sn-->0) VSIw->vistop=VSIw->vistop->next;
sn=VSIw->Rbottom-VSIw->Rtop;
RSbufinfo( w, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom);
if (n<=VSPBOTTOM) {
RSdellines(w,0,sn,n,0); /* Dont be destructive */
VSIcurson(w,VSIw->x, VSIw->y, 0); /* Dont force move */
VSredraw(w,0,(sn+1)-n,VSIw->maxwidth, sn);
}
else
VSredraw(w,0,0,VSIw->maxwidth, sn);
return(0);
}
VSscrolright(w,n)
int w,n;
{
int sn,x1,y1,x2,y2, lmmax;
if (VSvalids(w)!=0) return(-3);
lmmax= (VSIw->maxwidth-(VSIw->Rright - VSIw->Rleft));
if ( VSIw->Rleft+n > lmmax) /* Check against bounds */
n= lmmax- VSIw->Rleft;
if (n==0) return; /* Do nothing if appropriate */
VSIcuroff(w);
VSIw->Rleft +=n; /* Make new region */
VSIw->Rright +=n;
sn=VSIw->Rbottom-VSIw->Rtop;
RSmargininfo( w, lmmax, VSIw->Rleft);
RSdelcols(w,n);
VSIcurson(w,VSIw->x,VSIw->y, 0); /* Don't force move */
VSredraw(w, (VSIw->Rright-VSIw->Rleft)-n, 0, (VSIw->Rright - VSIw->Rleft), sn);
}
VSscrolleft(w,n)
int w,n;
{
int sn,x1,y1,x2,y2, lmmax;
if (VSvalids(w)!=0) return(-3);
lmmax= (VSIw->maxwidth-(VSIw->Rright - VSIw->Rleft));
if ( VSIw->Rleft-n < 0) /* Check against bounds */
n= VSIw->Rleft;
if (n==0) return; /* Do nothing if appropriate */
VSIcuroff(w);
VSIw->Rleft -=n; /* Make new region */
VSIw->Rright -=n;
sn=VSIw->Rbottom-VSIw->Rtop;
RSmargininfo( w, lmmax, VSIw->Rleft);
RSinscols(w,n);
VSIcurson(w,VSIw->x,VSIw->y, 0); /* Don't force move */
VSredraw(w,0,0,n, sn);
}
VSscrolcontrol(w,scrolon, offtop)
int w,scrolon;
{
if (VSvalids(w)!=0) return(-3);
if (scrolon>-1)
VSIw->savelines=scrolon;
if (offtop >-1)
VSIw->ESscroll =offtop;
return(0);
}
VSgetrgn(w,x1,y1,x2,y2)
int w,*x1,*y1,*x2,*y2;
{
if (VSvalids(w)!=0) return(-3);
*x1=VSIw->Rleft;
*y1=VSIw->Rtop;
*x2=VSIw->Rright;
*y2=VSIw->Rbottom;
return(0);
}
VSsnapshot(w)
int w;
{
if (VSvalids(w)!=0) return(-3);
return(0);
}
VSvalids(w)
int w;
{
if (VSinuse==0) return(-5); /* -5=no ports in use */
if (VSIwn==w) return(0); /* Currently set to that window */
if ((w>VSmax) || (w<0)) return(-6); /* blown out the top of the stuff */
VSIwn=w;
if (VSscreens[w].stat!=1) return(-3);/* not currently active */
VSIw=VSscreens[w].loc;
if (VSIw==0L) return(-3); /* no space allocated */
return(0);
}
VSmaxwidth(w)
int w;
{
if (VSvalids(w)!=0) return(-3);
return(VSIw->maxwidth);
}
VSline *VSIGetLineStart(w,y1)
{
VSline *ptr;
int n;
if (VSvalids(w)!=0) return( (VSline *) -3);
if (y1>=0)
return( VSIw->linest[y1]);
n= y1 - VSIw->Rtop; /* Number of lines from VISTOP to scroll forward */
ptr=VSIw->vistop;
while (n>0) { n--; ptr=ptr->next; }
while (n<0) { n++; ptr=ptr->prev; }
return( ptr);
}
char *VSIstrcopy( src, len, dest, table)
char *src, *dest;
int len, table;
{
char *p, *tempp;
int tblck;
p=src+len-1;
while((*p==' ') && (p>=src)) p--;
if (p<src) return(dest);
if (!table)
while( src<=p) *dest++=*src++;
else
while (src<=p) {
while ((src<=p) && (*src != ' '))
*dest++ = *src++;
if (src<p) {
tempp = dest;
tblck = 0;
while ((src<=p) && (*src== ' ')) {
*dest++ = *src++;
tblck++;
}
if (tblck >=table) {
*tempp++ = '\011';
dest = tempp;
}
}
}
return(dest);
}
long VSgettext(w, x1, y1, x2, y2, charp, max, EOLS, table)
int w,x1,y1,x2,y2;
char *charp, *EOLS;
long max;
int table;
{
int EOLlen;
int lx,ly, /* Upper bounds of selection */
ux,uy; /* Lower bounds of selection */
int maxwid;
char *origcp;
VSline *t;
if (VSvalids(w)!=0) return(-3);
EOLlen= strlen(EOLS);
maxwid= VSIw->maxwidth;
origcp= charp;
if ( y1 < -VSIw->numlines) {
y1= - VSIw->numlines;
x1= -1;
}
if ( y1 == y2) {
t=VSIGetLineStart(w,y1);
if ( x1 < x2 )
{ ux=x1; uy= y1; lx=x2; ly=y2; } /* Order the lower and */
else
{ ux=x2; uy= y2; lx=x1; ly=y1; } /* upper bounds */
charp = VSIstrcopy( &t->text[ux+1], lx-ux, charp, table);
if (lx==maxwid) *charp++=*EOLS;
}
else {
if ( y1< y2 )
{ ux=x1; uy= y1; lx=x2; ly=y2; } /* Order the lower and */
else
{ ux=x2; uy= y2; lx=x1; ly=y1; } /* upper bounds */
t=VSIGetLineStart(w, uy);
charp= VSIstrcopy( &t->text[ux+1], maxwid-ux, charp, table);
*charp++=*EOLS; uy++; t=t->next;
while (uy <ly && uy < VSPBOTTOM ) {
charp=VSIstrcopy(t->text,maxwid+1,charp, table);
*charp++=*EOLS;
t=t->next; uy++;
}
if (ly>VSPBOTTOM) lx=maxwid;
charp=VSIstrcopy( t->text, lx+1, charp, table);
if (lx>=maxwid )
*charp++=*EOLS;
}
return( charp - origcp );
}
VSgetlines(w)
int w;
{
if (VSvalids(w)!=0) return(-3);
return(VSIw->lines +1);
}
VSsetlines(w, lines)
int w,lines;
{
VSline **attrst, **linest; /* For storage of old ones */
VSline *VSInewlines(); /* For allocating new lines */
VSline *line; /* pointer to a line */
int i, j, oldlines;
char *temp, *tempa;
if (VSvalids(w)!=0) return(-3);
lines -= 1; /* Correct for internal use */
oldlines = VSIw->lines;
if (lines == oldlines)
return( 0);
VSIw->x=0;
VSIw->y=0;
VSIcurson(w,VSIw->x,VSIw->y, 1); /* keeps cursor from pointing outside of window */
VSIw->scrntop=VSIw->linest[0]; /* Move the top of the screen */
VSIw->vistop = VSIw->scrntop; /* Force a move to the top of the screen */
VSIlistndx( VSIw->scrntop, VSIw->attrst[0]); /* Re-sync the indices */
attrst = VSIw->attrst; /* Save previous line pointers */
linest = VSIw->linest;
VSIw->lines = lines;
VSIw->linest = (VSline **) malloc( sizeof( VSline *) * (lines+1));
VSIw->attrst = (VSline **) malloc( sizeof( VSline *) * (lines+1));
if (!VSIw->linest || !VSIw->attrst)
return(-2);
VSIw->linest[0] = VSInewlines(lines+1); /* get memory for new lines */
VSIw->attrst[0] = VSInewlines(lines+1); /* mem for new attributes */
if (VSIw->linest[0] && VSIw->attrst[0]) { /* mem is there */
VSIlistndx( VSIw->linest[0], VSIw->attrst[0]); /* Re-sync the indices */
/*
* insert newly malloced lines into scrollback list right after old linest.
*/
line = linest[oldlines]->next; /* save continuation */
linest[oldlines]->next = VSIw->linest[0];
VSIw->linest[lines]->next = line; /* restore continuation */
VSIw->linest[0]->prev = linest[oldlines]; /* backpointer */
if (line) { /* if there was a follower */
line = line->next;
line->prev = VSIw->linest[lines]; /* new prev for it */
}
VSIw->numlines += oldlines; /* we made more scrollback */
}
else { /* need more mem - emergency */
VSIfreelines(); /* release them all */
VSIw->linest[0] = VSInewlines(lines+1); /* get memory for new lines */
VSIw->attrst[0] = VSInewlines(lines+1); /* mem for new attributes */
if (!VSIw->linest[0] || !VSIw->attrst[0])
return(-2);
VSIw->buftop = VSIw->linest[0];
VSIw->numlines = 0;
}
VSIw->scrntop=VSIw->linest[0]; /* Move the top of the screen */
VSIw->vistop = VSIw->scrntop; /* Force a move to the top of the screen */
VSIlistndx( VSIw->scrntop, VSIw->attrst[0]);/* Re-sync the indices */
VSIw->attrst[0]->prev= VSIw->attrst[lines]; /* Make attr circ. */
VSIw->attrst[lines]->next= VSIw->attrst[0];
for (i = 0; i<=lines; i++) {
tempa=VSIw->attrst[ i]->text; /* Clear out this line */
temp =VSIw->linest[ i]->text;
for(j=0;j<=VSIw->allwidth; j++) {
*temp++ =' ';
*tempa++ =0;
}
}
VSIw->top = 0;
VSIw->bottom = lines;
VSIw->Rtop = 0;
VSIw->Rbottom = lines;
for (i=0 ; i<=oldlines; i++)
if (attrst[i]->mem) {
free( attrst[i]->text); /* Free attribute data */
free( attrst[i]); /* and header */
break; /* only one */
}
free( attrst); /* Nuke the previous pointers */
free( linest);
VSredraw(w,0,0,VSIw->maxwidth,lines);
RSbufinfo( w, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom);
return(VSIw->lines);
}