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
/
vsintern.c
< prev
next >
Wrap
Text File
|
1990-05-03
|
17KB
|
878 lines
#ifdef lint
static char *SCCSid = "%W% (NCSA) %G%";
#endif
/*
*
* Virtual Screen Kernel Internal Routines
* (vsintern.c)
* National Center for Supercomputing Applications
*
* by Gaige B. Paulsen
*
* This file contains the private internal calls for the NCSA
* Virtual Screen Kernel.
*
* Version Date Notes
* ------- ------ ---------------------------------------------------
* 0.01 861102 Initial coding -GBP
* 0.50 861113 First compiled edition -GBP
* 0.70 861114 Internal operation confirmed -GBP
* 2.1 871130 NCSA Telnet 2.1 -GBP
* 2.2 880715 NCSA Telnet 2.2 -GBP
*/
#include "vsdata.h"
#include "vskeys.h"
#define AL(x) VSIw->attrst[x]
#define VL(x) VSIw->linest[x]
#define vtp VSIw->top
#define btm VSIw->bottom
#define VSIclrattrib 0
#define Rrt VSIw->Rright
#define Rlt VSIw->Rleft
#define Rtp VSIw->Rtop
#define Rbm VSIw->Rbottom
pascal void DEBUGGER() extern 0xa9ff;
char *malloc();
VSIclip( x1, y1, x2, y2, n, offset)
int *x1, *x2, *y1, *y2, *n, *offset;
{
if (*n >=0) { *x2= *x1+*n-1; *y2= *y1; };
if (( *x1 > Rrt) || ( *y2 < Rtp)) return (-1);
if ( *x2 > Rrt) *x2= Rrt;
if ( *y2> Rbm) *y2= Rbm;
*x1 -= Rlt; *x2 -= Rlt;
*y1 -= Rtp; *y2 -= Rtp;
*offset = - *x1; if (*offset <0) *offset=0;
if (*x1<0) *x1=0;
if (*y1<0) *y1=0;
*n = *x2 - *x1 +1;
if (( *n <= 0) || ( *y2 - *y1 <0 ) ) return(-1);
return(0);
}
VSIcdellines( w, top, bottom, n, scrolled)
int w, top, bottom, n,scrolled;
{
int x1=0,x2=VSIw->maxwidth, tn = -1,offset;
if (VSIclip( &x1, &top, &x2, &bottom, &tn,&offset) )
return(-1);
tn =bottom-top;
if (tn <n) n=tn;
RSdellines( w, top, bottom, n,scrolled);
return(0); /* I delete the whole thing! */
}
VSIcinslines( w, top, bottom, n,scrolled)
int w, top, bottom, n, scrolled;
{
int x1=0,x2=VSIw->maxwidth, tn= -1,offset;
if (VSIclip( &x1, &top, &x2, &bottom, &tn, &offset) )
return(-1);
tn =bottom-top;
if (tn <n) n=tn;
RSinslines( w, top, bottom, n,scrolled);
}
VSIcurson( w,x,y,ForceMove)
int w,x,y,ForceMove;
{
int ox=x,oy=y,x2,y2,n=1,offset;
if (!VSIclip(&x,&y,&x2,&y2,&n, &offset) )
RScurson( w, x, y);
else if (ForceMove) {
x2= Rbm-Rtp;
if (x2 >=VSPBOTTOM)
VSsetrgn(VSIwn,Rlt,VSPBOTTOM-x2,Rrt,VSPBOTTOM);
else {
if (y>0) VSscrolforward(VSIwn, y );
else VSscrolback(VSIwn, -y);
}
x=ox; y=oy; /* Restore from previous */
n=1;
/* if (!VSIclip(&x,&y,&x2,&y2,&n, &offset) )
RScurson( w, x, y);
*/
}
}
VSIcuroff( w)
int w;
{
int x=VSIw->x, y=VSIw->y, x2,y2,n=1,offset;
if (!VSIclip(&x,&y,&x2,&y2,&n, &offset) )
RScursoff(w);
}
VSIreset()
{
VSIw->top=0;
VSIw->bottom=VSPBOTTOM;
VSIw->parmptr=0;
VSIw->escflg=0;
VSIw->DECAWM=0;
VSIw->DECCKM=0;
VSIw->DECPAM=0;
VSIw->DECORG=0;
VSIw->IRM=0;
VSIw->attrib=0;
VSIw->Pattrib=-1;
VSIw->x=0;
VSIw->y=0;
VSIw->charset=0;
VSIes();
VSItabinit();
}
VSItabinit()
{
int x=0;
VSItabclear();
while(x<=VSIw->allwidth) { VSIw->tabs[x]='x';x+=8;}
VSIw->tabs[VSIw->allwidth]='x';
}
VSItabclear()
{
int x=0;
while (x<=VSIw->allwidth) {
VSIw->tabs[x]=' ';
x++;
}
}
VSIlistmove(TD,BD,TI,BI)
register VSline *TD,*BD,*TI,*BI;
{
if (TD->prev!=0L) TD->prev->next=BD->next; /* Maintain circularity */
if (BD->next!=0L) BD->next->prev=TD->prev;
TD->prev=TI; /* Place the node in its new home */
BD->next=BI;
if (TI!=0L) TI->next=TD; /* Ditto prev->prev */
if (BI!=0L) BI->prev=BD;
}
VSIlistndx(ts,as)
register VSline *ts,*as;
{
register int i;
for(i=0; i<=VSPBOTTOM;i++) {
AL(i)=as;
VL(i)=ts;
ts=ts->next;
as=as->next;
}
}
VSIdellines(n,s)
int n,s;
{
int i,j, attop= (VSIw->vistop == VSIw->scrntop);
char *ta,*tt;
VSline *as,*ts,*TD,*BD,*TI,*BI,*itt,*ita;
if (s<0) s=VSIw->y;
if ( s+n-1 > VSIw->bottom) n = VSIw->bottom -s +1;
ts=VL(0)->prev;
TD=VL(s);
BD=VL(s+n-1);
TI=VL(VSIw->bottom);
BI=TI->next;
itt=TD;
if ((TI!=BD))
VSIlistmove(TD,BD,TI,BI);
if (s==0 || n>VSPBOTTOM) as=AL( n);
else as=AL(0);
TD=AL(s);
BD=AL(s+n-1);
TI=AL(VSIw->bottom);
BI=TI->next;
if (TD!=BI && TI!=BD)
VSIlistmove(TD,BD,TI,BI);
ita=TD;
for(i=0; i<n; i++) {
ta=ita->text;
tt=itt->text;
for(j=0; j<=VSIw->allwidth; j++) {
*tt++=' ';
*ta++=VSIclrattrib;
}
ita=ita->next;
itt=itt->next;
}
VSIw->scrntop = ts->next;
if (attop) VSIw->vistop = VSIw->scrntop;
VSIlistndx(ts->next,as);
VSIcdellines(VSIwn,s, VSIw->bottom,n, -1); /* Destroy selection area if this is called */
}
VSIinslines(n,s)
int n,s;
{
int i,j, attop= (VSIw->vistop == VSIw->scrntop);
char *ta,*tt;
VSline *as,*ts,*TD,*BD,*TI,*BI,*itt,*ita;
if (s<0) s=VSIw->y;
if ( s+n-1 > VSIw->bottom) n = VSIw->bottom -s +1;
ts=VL(0)->prev;
BI=VL(s);
TI=BI->prev;
TD=VL(VSIw->bottom-n+1);
BD=VL(VSIw->bottom);
itt=TD;
if (TD!=BI)
VSIlistmove(TD,BD,TI,BI);
if (s==0 || n>VSPBOTTOM) as=AL( VSIw->bottom-n+1);
else as=AL(0);
BI=AL(s);
TI=BI->prev;
TD=AL(VSIw->bottom-n+1);
BD=AL(VSIw->bottom);
if (TD!=BI && TI!=BD)
VSIlistmove(TD,BD,TI,BI);
ita=TD;
for(i=0; i<n; i++) {
tt=itt->text;
ta=ita->text;
for(j=0; j<=VSIw->allwidth; j++) {
*tt++=' ';
*ta++=VSIclrattrib;
}
itt=itt->next;
ita=ita->next;
}
VSIw->scrntop = ts->next;
if (attop) VSIw->vistop = VSIw->scrntop;
VSIlistndx(ts->next,as);
VSIcinslines(VSIwn, s,VSIw->bottom, n, -1); /* Destroy selection area if this is called tooo */
}
VSIwrapnow( xp,yp)
int *xp, *yp;
{
if (VSIw->x > VSIw->maxwidth) {
VSIw->x=0;
VSIindex();
}
*xp=VSIw->x;
*yp=VSIw->y;
}
VSIeeol()
{
char *tt,*ta;
int x1=VSIw->x, y1=VSIw->y, x2=VSIw->maxwidth, y2=VSIw->y, n= -1,offset;
int i;
VSIwrapnow( &x1, &y1);
y2=y1;
ta = &AL(y1)->text[x1];
tt = &VL(y1)->text[x1];
for(i=VSIw->allwidth-x1+1;i>0; i--) {
*ta++=VSIclrattrib;
*tt++=' ';
}
if ( !VSIclip( &x1,&y1,&x2,&y2,&n, &offset))
RSerase(VSIwn,x1,y1,x2,y2);
}
VSIdelchars(x)
int x;
{
int i;
int x1=VSIw->x, y1=VSIw->y, x2=VSIw->maxwidth, y2=VSIw->y, n= -1,offset;
char *tempa,*temp;
VSIwrapnow( &x1, &y1);
y2=y1;
if (x>VSIw->maxwidth) x=VSIw->maxwidth;
tempa=VSIw->attrst[y1]->text;
temp =VSIw->linest[y1]->text;
for(i=x1; i<=VSIw->maxwidth-x;i++) {
temp[i]=temp[x+i];
tempa[i]=tempa[x+i];
}
for(i=VSIw->maxwidth-x+1;i<=VSIw->allwidth; i++) {
temp[i]=' ';
tempa[i]=VSIclrattrib;
}
if ( !VSIclip( &x1,&y1,&x2,&y2,&n, &offset)) {
if (VSIw->VSIDC)
RSdelchars(VSIwn, x1, y1, x);
else
RSdraw(VSIwn, x1, y1,VSIw->attrib, n,
&VSIw->linest[y1]->text[x1]);
}
}
VSIindex()
{
#ifdef OLDM
if( ++VSIw->y > VSIw->bottom) {
VSIw->y=VSIw->bottom;
VSIscroll();
}
#endif
if (VSIw->y >= VSIw->bottom) { /* BYU mod - changed "==" to ">=" */
VSIscroll();
}
else
VSIw->y++;
}
VSline *VSInewlines(nlines)
int nlines;
{
VSline *t2;
char *t;
register int i;
if (!RSokmem(30000)) /* don't use up end of mem for scrollback */
return(0L);
if ((t = malloc( nlines * (VSIw->allwidth+1))) !=0L) {
if ((t2 = (VSline *)malloc(nlines*sizeof(VSline))) !=0L)
t2->text=t;
else { free(t); return(0L); } /* Return on bad malloc */
}
else return(0L); /* Return on bad malloc */
/*
* indicate to the free routine that the first record is the one to free.
*/
t2->mem = 1;
t2->next = t2+1; /* point to next one */
/*
* Take our allocation for multiple lines and fill in the structures to
* point to the right text fields and connect the doubly-linked chain.
*
*/
for (i=1; i<nlines; i++) {
t += (VSIw->allwidth+1); /* inc to next text space for a line */
(*(t2+i)).mem = 0;
(*(t2+i)).text = t;
(*(t2+i)).prev = t2+i-1; /* point back one */
(*(t2+i)).next = t2+i+1; /* point forward one */
}
t2->prev = 0L; /* first one has no prev yet */
(*(t2+nlines-1)).next = 0L; /* last one is NULL terminated */
return(t2);
}
VSIscroll()
{
register char *temp,*tempa;
VSline *tmp;
register int i;
int tx1,tx2,ty1,ty2, tn,offset;
tx1=ty1=0; tn=132;
if (!VSIclip( &tx1, &ty1,&tx2,&ty2, &tn, &offset) )
RSdrawsep( VSIwn, ty1, 1); /* Draw Separator */
if ((VSIw->y < VSIw->top) || (VSIw->y > VSIw->bottom)) /* BYU mod */
return; /* BYU mod */
if ( (!VSIw->savelines) || (VSIw->top !=0) || (VSIw->bottom != VSPBOTTOM))
VSIdellines(1,VSIw->top);
else {
if ( VL(VSPBOTTOM)->next == 0L) { /* need wrap or storage */
i = VSIw->maxlines - VSIw->numlines; /* number of lines needed */
if (i > 100) i = 100;
if (( i > 0 ) && (tmp = VSInewlines(i)) !=0L ) {
VL(VSPBOTTOM)->next = tmp; /* ADD some lines */
tmp->prev= VL(btm);
VSIw->numlines++; /* count one */
RSbufinfo(VSIwn, VSIw->numlines,VSIw->Rtop, VSIw->Rbottom);
}
else {
VL(btm)->next =VSIw->buftop; /* Make it circular */
VSIw->buftop->prev= VL(btm);
VSIw->buftop=VSIw->buftop->next; /* step one forward */
}
}
else {
if ( VL(btm)->next == VSIw->buftop)
VSIw->buftop=VSIw->buftop->next; /* if we are in old terr. loop*/
else
VSIw->numlines++; /* count it */
}
VSIw->scrntop=VSIw->scrntop->next;
VSIlistndx( VSIw->scrntop, AL(1));
if (VSIcdellines(VSIwn,VSIw->Rtop, VSIw->Rbottom,1,1) ) { /* Dont destroy select */
/* If we did not show on screen then we mush do dis */
if (VSIw->Rtop > -VSIw->numlines) { /* If we are not at the top..... */
VSIw->Rtop--; VSIw->Rbottom--; /* Then we should move down */
}
else { /* But if we're at the top.... */
/* The region remains the same .. */
VSIw->vistop=VSIw->vistop->next;/* and move the vistop as */
RSdellines( VSIwn, 0,Rbm-Rtp,1,1);/* we also delete the top line */
} /* well.... (but don't destroy selection) */
}
else {
VSIw->vistop=VSIw->vistop->next;
}
tempa=AL(VSPBOTTOM)->text;
temp =VL(VSPBOTTOM)->text;
for(i=0;i<=VSIw->allwidth; i++) {
*temp++=' ';
*tempa++=0;
}
}
tx1=ty1=0; tn=132;
if (!VSIclip( &tx1, &ty1,&tx2,&ty2, &tn, &offset) )
RSdrawsep( VSIwn, ty1, 1); /* Draw Separator */
}
VSIscroff()
{
register char *temp,*tempa;
VSline *tmp,*VSInewlines();
register int i,j;
if ((!VSIw->savelines) || (VSIw->top !=0) || (VSIw->bottom != VSPBOTTOM))
return;
tmp = VL(VSPBOTTOM); /* we need VSPBOTTOM+1 more lines */
for (i = 0; i<=VSPBOTTOM; i++) {
if (!tmp->next) { /* don't have enough */
j = VSIw->maxlines - VSIw->numlines - i;/* how much more scrollback? */
if (j > 100) j = 100;
if (j <= 0) { /* make it circular instead */
tmp->next = VSIw->buftop;
VSIw->buftop->prev = tmp; /* connect it up */
}
else {
if (j < VSPBOTTOM - i + 1)
j = VSPBOTTOM - i + 1;
/* allocate enough for whole screen */
if ((tmp->next = VSInewlines(j)) != 0L )
tmp->next->prev = tmp; /* link it up */
else { /* if all else fails, go circular */
tmp->next = VSIw->buftop;
VSIw->buftop->prev = tmp;
}
}
break; /* only allocate once is enough */
}
tmp = tmp->next;
}
/*
* at this point, we know we have enough memory for the whole scroll.
* It might be wraparound, might not.
*/
for (i = 0; i<=VSPBOTTOM; i++) {
if ( VL(VSPBOTTOM)->next == VSIw->buftop)
VSIw->buftop=VSIw->buftop->next; /* if we are in old terr. loop*/
else
VSIw->numlines++; /* otherwise, count it in */
VSIw->scrntop=VSIw->scrntop->next;
VSIlistndx( VSIw->scrntop, AL(1));
}
VSIw->vistop = VSIw->scrntop;
RSbufinfo(VSIwn, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom);
return(0);
}
VSIfreelines()
{
register VSline *p,*oldp,*startp;
/*
* get rid of the allocated scrollback lines.
* See mem notes under VSnewscreen. There is only one mem flag per block, so
* we can link up the flag records and then free them as a short list of blocks
* instead of a long list of linked lines.
*/
p=VSIw->buftop;
oldp = startp = NULL;
do {
if (p->mem) {
if (!oldp)
startp = oldp = p; /* remember start of list */
else {
oldp->next = p; /* link in mem records */
oldp = p;
}
}
p=p->next;
} while ( (p!=0L) && (p!=VSIw->buftop) );
oldp->next = 0L; /* stop list */
p = startp;
while (p) {
oldp = p; /* don't free yourself! */
p = p->next; /* step through list, freeing */
free(oldp->text);
free(oldp);
}
}
VSIrindex()
{
if(--VSIw->y < VSIw->top)
{ VSIw->y=VSIw->top;
VSIinslines(1,VSIw->top);
}
}
VSIebol()
{
char *tt,*ta;
int x1=0, y1=VSIw->y, x2=VSIw->x, y2=VSIw->y, n= -1, offset;
int i;
VSIwrapnow( &x2, &y1);
y2=y1;
ta = &AL(y1)->text[0];
tt = &VL(y1)->text[0];
for(i=0;i<=x2; i++) {
*ta++=VSIclrattrib;
*tt++=' ';
}
if ( !VSIclip( &x1,&y1,&x2,&y2,&n,&offset))
RSerase(VSIwn,x1,y1,x2,y2);
}
VSIel(s)
int s;
{
char *tt,*ta;
int x1=0, y1=s, x2=VSIw->maxwidth, y2=s, n= -1,offset;
int i;
if (s<0) {
VSIwrapnow( &x1, &y1);
s=y2=y1;
x1=0;
}
ta = &AL(s)->text[0];
tt = &VL(s)->text[0];
for(i=0;i<=VSIw->allwidth; i++) {
*ta++=VSIclrattrib;
*tt++=' ';
}
if ( !VSIclip( &x1,&y1,&x2,&y2,&n, &offset))
RSerase(VSIwn,x1,y1,x2,y2);
}
VSIelo(s)
{
char *tt,*ta;
int i,j;
/* VSIwrapnow( &i, &j); */
if (s<0) s=VSIw->y;
ta = &AL(s)->text[0];
tt = &VL(s)->text[0];
for(i=0;i<=VSIw->allwidth; i++) {
*ta++=VSIclrattrib;
*tt++=' ';
}
}
VSIeeos()
{
int i;
int x1=0, y1=VSIw->y+1, x2=VSIw->maxwidth, y2=VSPBOTTOM, n= -1,offset;
VSIwrapnow( &x1, &y1);
y1++;
x1=0;
i=y1;
if ( !VSIclip( &x1,&y1,&x2,&y2,&n, &offset))
RSerase(VSIwn,x1,y1,x2,y2);
VSIeeol();
while(i<=VSPBOTTOM) {
VSIelo(i);
i++;
}
if (VSIw->y<VSPBOTTOM && (VSIw->x <= VSIw->maxwidth))
if ( !VSIclip( &x1,&y1,&x2,&y2,&n,&offset))
RSerase(VSIwn,x1,y1,x2,y2);
}
VSIebos()
{
int i;
int x1, y1, x2=VSIw->maxwidth, y2, n= -1,offset;
VSIwrapnow( &x1, &y1);
y2=y1-1;
x1=0;
y1=0;
VSIebol();
i=0;
while(i< (y2+1) ) { /* Equiv of VSIw->y */
VSIelo(i);
i++;
}
if (y2>=0) /* Equiv of VSIw->y >0 */
if ( !VSIclip( &x1,&y1,&x2,&y2,&n, &offset))
RSerase(VSIwn,x1,y1,x2,y2);
}
VSIes()
{
int i;
int x1=0, y1=0, x2=VSIw->maxwidth, y2=VSPBOTTOM, n= -1,offset;
if (VSIw->ESscroll)
VSIscroff();
for(i=0;i<=VSPBOTTOM;i++)
VSIelo(i);
if ( !VSIclip( &x1,&y1,&x2,&y2,&n, &offset))
RSerase(VSIwn,x1,y1,x2,y2);
VSIw->vistop = VSIw->scrntop;
}
VSIrange() /* check and resolve range errors on x and y */
{
int wrap=0;
if (VSIw->DECAWM) wrap=1;
if (VSIw->x<0) VSIw->x=0;
if (VSIw->x>(VSIw->maxwidth+wrap))
VSIw->x=VSIw->maxwidth+wrap;
if (VSIw->y<0) VSIw->y=0;
if (VSIw->y>VSPBOTTOM) VSIw->y=VSPBOTTOM;
}
VTsendpos()
{
char tempbuf[19];
int x=VSIw->x, y=VSIw->y;
if (x>VSIw->maxwidth) {
x=0;y++;
}
if (y>VSPBOTTOM) y=VSPBOTTOM;
sprintf(tempbuf,"\033[%d;%dR",y+1,x+1);
RSsendstring(VSIwn,tempbuf,strlen(tempbuf));
}
VTsendstat()
{
RSsendstring(VSIwn,"\033[0n",4);
}
VTsendident()
{
#ifdef VT100RESP
if (VSIw->allwidth >80)
RSsendstring(VSIwn,"\033[?4;6c",7);
else
RSsendstring(VSIwn,"\033[?1;6c",7);
#endif VT100RESP
RSsendstring(VSIwn, "\033[?6c",5);
}
VTalign()
{
char *tt;
int i,j;
VSIes(); /* erase the screen */
for (j=0; j<VSPBOTTOM; j++) {
tt = &VL(j)->text[0];
for(i=0;i<=VSIw->maxwidth; i++) {
*tt++='E';
}
}
VSredraw( VSIwn, 0, 0, (VSIw->Rright - VSIw->Rleft), (VSIw->Rbottom - VSIw->Rtop) );
}
VSIapclear()
{
VSIw->parmptr=6;
while(VSIw->parmptr-->0) VSIw->parms[VSIw->parmptr] = -1;
VSIw->parmptr=0;
}
VSIsetoption(toggle)
int toggle;
{
int WindWidth= VSIw->Rright - VSIw->Rleft;
switch(VSIw->parms[0]) {
case -2:
switch(VSIw->parms[1]){
case 1:
VSIw->DECCKM=toggle;
break;
case 3:
VSIw->x=VSIw->y=0; /* Clear the screen, mama! */
VSIes();
if (toggle) { /* 132 column mode */
VSIw->maxwidth=VSIw->allwidth;
}
else {
VSIw->maxwidth= 79;
}
RSmargininfo( VSIwn, VSIw->maxwidth- WindWidth, VSIw->Rleft);
break;
case 6:
VSIw->DECORG = toggle;
break;
case 7:
VSIw->DECAWM=toggle;
break;
default:
break;
}
break;
case 4:
VSIw->IRM=toggle;
break;
default:
break;
}
}
VSItab()
{
if (VSIw->x>=VSIw->maxwidth) {
VSIw->x=VSIw->maxwidth;
return(0);
}
VSIw->x++;
while( (VSIw->tabs[VSIw->x]!='x') && (VSIw->x<VSIw->maxwidth)) VSIw->x++;
return(0);
}
VSIinschar(x)
int x;
{
int i,j;
char *tempa,*temp;
VSIwrapnow( &i, &j);
tempa=VSIw->attrst[VSIw->y]->text;
temp =VSIw->linest[VSIw->y]->text;
for(i=VSIw->maxwidth-x; i>=VSIw->x; i--) {
temp[x+i]=temp[i];
tempa[x+i]=tempa[i];
}
for(i=VSIw->x;i<VSIw->x+x; i++) {
temp[i]=' ';
tempa[i]=VSIclrattrib;
}
}
VSIinsstring(len,start)
int len;
char *start;
{
if (VSIw->VSIDC)
RSinsstring(VSIwn,VSIw->x-len,VSIw->y,VSIw->attrib,len,start);
else
RSdraw(VSIwn,VSIw->x-len,VSIw->y,VSIw->attrib,
VSIw->maxwidth-VSIw->x+len+1,start);
}
VSIsave()
{
VSIw->Px=VSIw->x;
VSIw->Py=VSIw->y;
VSIw->Pattrib=VSIw->attrib;
}
VSIrestore()
{
if (VSIw->Pattrib < 0)
return;
VSIw->x=VSIw->Px;
VSIw->y=VSIw->Py;
VSIrange();
VSIw->attrib=VSinattr(VSIw->Pattrib);
}
VSIdraw( VSIwn, x, y, a, len, c)
int VSIwn,x,y,a,len;
char *c;
{
int oy=y,x2,y2,offset;
if ( !VSIclip( &x, &y, &x2, &y2, &len, &offset) )
RSdraw( VSIwn, x, y, a, len, c+(offset) );
}