home *** CD-ROM | disk | FTP | other *** search
Wrap
#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 <stdio.h> #include <string.h> #include <stdlib.h> #ifdef MSC #include <malloc.h> #endif #ifdef MEMORY_DEBUG #include "memdebug.h" #endif #include "vsdata.h" #include "vskeys.h" #include "externs.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 /* clip a requested area of the screen to the actuall virtual screen window */ int VSIclip(x1,y1,x2,y2,n,offset) int *x1, /* the requested left edge */ *x2, /* the requested right edge */ *y1, /* the requested top edge */ *y2, /* the requested bottom edge */ *n, /* the requested width of the virtual window */ *offset; { if(*n>=0) { /* set the requested right edge of the window */ *x2=*x1+*n-1; *y2=*y1; } /* end if */ if((*x1>Rrt) || (*y2<Rtp)) /* check for invalid invalid left and bottom edges */ return(-1); if(*x2>Rrt) /* clip the right edge to the right edge of the virtual screen */ *x2=Rrt; if(*y2>Rbm) /* clip the bottom edge to the bottom edge of the virtual screen */ *y2=Rbm; *x1-=Rlt; /* adjust to represent actual screen coor. */ *x2-=Rlt; *y1-=Rtp; *y2-=Rtp; *offset=-*x1; if(*offset<0) *offset=0; if(*x1<0) /* clip left edge to top of virtual screen */ *x1=0; if(*y1<0) /* clip top edge to top of virtual screen */ *y1=0; *n=*x2-*x1+1; /* set the width of the clipped region */ if((*n<=0) || (*y2-*y1<0)) /* check whether the clipped region really exists */ return(-1); return(0); } int 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! */ } int 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); return(0); } void VSIcurson(w,x,y,ForceMove) int w, x,y, ForceMove; { int #ifdef OLD_WAY ox=x,oy=y, #endif 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); } /* end else */ /* Restore from previous */ #ifdef OLD_WAY x=ox; y=oy; n=1; if(!VSIclip(&x,&y,&x2,&y2,&n,&offset)) RScurson(w,x,y); #endif } /* end if */ } void 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); } VSline *VSInewline(void ) { VSline *t2; char *t; if((t=malloc(VSIw->allwidth+1)) !=NULL) { if((t2=(VSline *)malloc(sizeof(VSline))) !=NULL) t2->text=t; else { /* Return on bad malloc */ free(t); return(NULL); } /* end else */ } /* end if */ else return(NULL); /* Return on bad malloc */ t2->next=t2->prev=NULL; return(t2); } void VSIlistndx(ts,as) VSline *ts,*as; { int i; for(i=0; i<=VSPBOTTOM; i++) { AL(i)=as; VL(i)=ts; ts=ts->next; as=as->next; } /* end for */ } void VSIscroff() { VSline *tmp; int i; if(VL(VSPBOTTOM)->next !=NULL) { for(i=0; i<=VSPBOTTOM; i++) { if(VL(VSPBOTTOM)->next==VSIw->buftop) VSIw->buftop=VSIw->buftop->next; /* if we are in old terr. loop */ VSIw->scrntop=VSIw->scrntop->next; VSIlistndx(VSIw->scrntop,AL(1)); } } else { for(i=0; i<=VSPBOTTOM; i++) { if((VSIw->numlines<VSIw->maxlines)&&(tmp=VSInewline()) !=NULL ) { VL(VSPBOTTOM)->next=tmp; /* ADD A LINE */ tmp->prev=VL(VSPBOTTOM); VSIw->numlines++; } else { if(VL(VSPBOTTOM)->next==NULL) { VL(VSPBOTTOM)->next=VSIw->buftop; /* Make it circular */ VSIw->buftop->prev=VL(VSPBOTTOM); } if(VL(VSPBOTTOM)->next==VSIw->buftop) VSIw->buftop=VSIw->buftop->next;/* if we are in old terr. loop*/ } VSIw->scrntop=VSIw->scrntop->next; VSIlistndx(VSIw->scrntop,AL(1)); } RSbufinfo(VSIwn,VSIw->numlines,VSIw->Rtop,VSIw->Rbottom); } } void VSIelo(s) int s; { char *tt,*ta; int i; /* 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++=' '; } /* end for */ } void VSIes(void) { 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; } void VSItabclear(void) { int x=0; while(x<=VSIw->allwidth) { VSIw->tabs[x]=' '; x++; } /* end while */ } void VSItabinit() { int x=0; VSItabclear(); while(x<=VSIw->allwidth) { VSIw->tabs[x]='x'; x+=8; } /* end while */ VSIw->tabs[VSIw->allwidth]='x'; } void 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->Pattrib=-1; */ VSIw->IRM=0; VSIw->attrib=0; VSIw->x=0; VSIw->y=0; VSIw->charset=0; VSIes(); VSItabinit(); set_vtwrap(VSIwn,VSIw->DECAWM); /* QAK - 7/27/90: added because resetting the virtual screen's wrapping flag doesn't reset telnet window's wrapping */ } void VSIlistmove(TD,BD,TI,BI) VSline *TD,*BD,*TI,*BI; { if(TD->prev!=NULL) TD->prev->next=BD->next; /* Maintain circularity */ if(BD->next!=NULL) BD->next->prev=TD->prev; TD->prev=TI; /* Place the node in its new home */ BD->next=BI; if(TI!=NULL) TI->next=TD; /* Ditto prev->prev */ if(BI!=NULL) BI->prev=BD; } void 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; } /* end for */ ita=ita->next; itt=itt->next; } /* end for */ 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 */ } void 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; } /* end for */ itt=itt->next; ita=ita->next; } /* end for */ 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 */ } /* scroll the virtual screen up one line */ void VSIscroll(void) { char *temp,*tempa; VSline *tmp; int i; int tx1=0,ty1=0, tx2,ty2, tn=132, offset; if(!VSIclip(&tx1,&ty1,&tx2,&ty2,&tn,&offset)) RSdrawsep(VSIwn,ty1,1); /* Draw Separator */ if((!VSIw->savelines) || (VSIw->top!=0) || (VSIw->bottom!=VSPBOTTOM)) /* if we are not using scroll back, or still in the middle of the screen, delete the line which scroll off the top */ VSIdellines(1,VSIw->top); else { if((VL(VSPBOTTOM)->next==NULL) && (VSIw->numlines<VSIw->maxlines) && (tmp=VSInewline())!=NULL) { VL(VSPBOTTOM)->next=tmp; /* ADD A LINE to the scroll back list */ tmp->prev=VL(btm); VSIw->numlines++; RSbufinfo(VSIwn,VSIw->numlines,VSIw->Rtop,VSIw->Rbottom); } /* end if */ else { if(VL(btm)->next==NULL) { VL(btm)->next=VSIw->buftop; /* Make it circular */ VSIw->buftop->prev=VL(btm); } /* end if */ if(VL(btm)->next==VSIw->buftop) VSIw->buftop=VSIw->buftop->next; /* if we are in old terr. loop*/ } /* end else */ #ifdef OLD_WAY attop=(VSIw->vistop==VSIw->scrntop); /* set this when scrollback isn't possible yet */ #endif VSIw->scrntop=VSIw->scrntop->next; /* move the top of the screen down one position */ VSIlistndx(VSIw->scrntop,AL(1)); if(VSIcdellines(VSIwn,VSIw->Rtop,VSIw->Rbottom,1,1)) { /* scroll real screen up, but Dont destroy select */ /* If we did not show on screen then we must do this */ if(VSIw->Rtop>-VSIw->numlines) { /* If we are not at the top..... */ VSIw->Rtop--; /* Then we should move down */ VSIw->Rbottom--; } 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[i]=' '; tempa[i]=0; } } /* end else */ tx1=ty1=0; tn=132; if(!VSIclip(&tx1,&ty1,&tx2,&ty2,&tn,&offset)) RSdrawsep(VSIwn,ty1,1); /* Draw Separator */ } /* increment the y position we are on in the virtual screen, and check whether * that means we need to scroll */ void VSIindex(void) { #ifdef OLD_WAY if(++VSIw->y > VSIw->bottom) { VSIw->y=VSIw->bottom; VSIscroll(); } /* end if */ #endif if(VSIw->y==VSIw->bottom) VSIscroll(); else VSIw->y++; } void VSIwrapnow(xp,yp) int *xp,*yp; { if(VSIw->x > VSIw->maxwidth) { VSIw->x=0; VSIindex(); } /* end if */ *xp=VSIw->x; *yp=VSIw->y; } void VSIeeol(void) { char *tt,*ta; int x1=VSIw->x,y1=VSIw->y, x2=VSIw->maxwidth,y2=VSIw->y, n=(-1), offset; register 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++=' '; } /* end for */ if(!VSIclip(&x1,&y1,&x2,&y2,&n,&offset)) RSerase(VSIwn,x1,y1,x2,y2); } void 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]; } /* end for */ for(i=VSIw->maxwidth-x+1; i<=VSIw->allwidth; i++) { temp[i]=' '; tempa[i]=VSIclrattrib; } /* end for */ 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]); } void VSIrindex(void) { #ifdef OLD_WAY if(--VSIw->y < VSIw->top ) { VSIw->y=VSIw->top; VSIinslines(1,VSIw->top); } /* end if */ #endif if(VSIw->y==VSIw->top) VSIinslines(1,VSIw->top); else VSIw->y--; } void VSIebol(void) { char *tt,*ta; int x1=0,y1=VSIw->y, x2=VSIw->x,y2=VSIw->y, n=(-1), offset; register 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++=' '; } /* end for */ if(!VSIclip(&x1,&y1,&x2,&y2,&n,&offset)) RSerase(VSIwn,x1,y1,x2,y2); } void VSIel(s) int s; { char *tt,*ta; int x1=0,y1=s, x2=VSIw->maxwidth,y2=s, n=(-1), offset; register int i; if(s<0) { VSIwrapnow(&x1,&y1); s=y2=y1; x1=0; } /* end if */ ta=&AL(s)->text[0]; tt=&VL(s)->text[0]; for(i=0; i<=VSIw->allwidth; i++) { *ta++=VSIclrattrib; *tt++=' '; } /* end for */ if(!VSIclip(&x1,&y1,&x2,&y2,&n,&offset)) RSerase(VSIwn,x1,y1,x2,y2); } void VSIeeos(void) { register 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++; } /* end while */ if(VSIw->y < VSPBOTTOM && (VSIw->x <= VSIw->maxwidth)) if(!VSIclip(&x1,&y1,&x2,&y2,&n,&offset)) RSerase(VSIwn,x1,y1,x2,y2); } void VSIebos(void) { register 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++; } /* end while */ if(y2>=0) /* Equiv of VSIw->y>0 */ if(!VSIclip(&x1,&y1,&x2,&y2,&n,&offset)) RSerase(VSIwn,x1,y1,x2,y2); } void VSIrange(void) /* 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; } void VTsendpos(void) /* send cursor position to host */ { char tempbuf[15]; int x=VSIw->x, y=VSIw->y; if(x > VSIw->maxwidth) { x=0; y++; } /* end if */ if(y>VSPBOTTOM) y=VSPBOTTOM; sprintf(tempbuf,"\033[%d;%dR",y+1,x+1); RSsendstring(VSIwn,tempbuf,strlen(tempbuf)); } void VTsendstat(void) /* send OK status back to host */ { RSsendstring(VSIwn,"\033[0n",4); } void VTsendident(void) /* send terminal capabilities to host */ { #define THISWAY #ifdef THISWAY RSsendstring(VSIwn,"\033[?6c",5); /* GPO & AVO options supported */ #else RSsendstring(VSIwn,"\033[?1c",5); /* GPO & AVO options supported */ #endif } void VTalign(void) /* vt100 alignment, fill screen with 'E's */ { char *tt; register 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'; } /* end for */ VSredraw(VSIwn,0,0,(VSIw->Rright-VSIw->Rleft),(VSIw->Rbottom-VSIw->Rtop)); } /* reset all the ANSI parameters back to the default state */ void VSIapclear(void) { for(VSIw->parmptr=5; VSIw->parmptr>=0; VSIw->parmptr--) VSIw->parms[VSIw->parmptr]=-1; VSIw->parmptr=0; } void VSIsetoption(toggle) int toggle; { int WindWidth=(VSIw->Rright-VSIw->Rleft); switch(VSIw->parms[0]) { case -2: switch(VSIw->parms[1]) { case 1: /* set/reset cursor key mode */ VSIw->DECCKM=toggle; break; #ifdef NOT_SUPPORTED case 2: /* set/reset ANSI/vt52 mode */ break; #endif case 3: /* set/reset column mode */ 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; #ifdef NOT_SUPPORTED case 4: /* set/reset scrolling mode */ case 5: /* set/reset screen mode */ case 6: /* set/rest origin mode */ VSIw->DECORG = toggle; break; #endif case 7: /* set/reset wrap mode */ VSIw->DECAWM=toggle; set_vtwrap(VSIwn,VSIw->DECAWM); /* QAK - 7/27/90: added because resetting the virtual screen's wrapping flag doesn't reset telnet window's wrapping */ break; #ifdef NOT_SUPPORTED case 8: /* set/reset autorepeat mode */ case 9: /* set/reset interlace mode */ break; #endif default: break; } /* end switch */ break; case 4: VSIw->IRM=toggle; break; default: break; } /* end switch */ } void VSItab(void) { if(VSIw->x>=VSIw->maxwidth) VSIw->x=VSIw->maxwidth; VSIw->x++; while((VSIw->tabs[VSIw->x] != 'x') && (VSIw->x < VSIw->maxwidth)) VSIw->x++; } void 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]; } /* end for */ for(i=VSIw->x; i<VSIw->x+x; i++) { temp[i]=' '; tempa[i]=VSIclrattrib; } /* end for */ } void 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); } void VSIsave(void) { VSIw->Px=VSIw->x; VSIw->Py=VSIw->y; VSIw->Pattrib=VSIw->attrib; } void VSIrestore(void) { VSIw->x=VSIw->Px; VSIw->y=VSIw->Py; VSIrange(); VSIw->attrib=VSinattr(VSIw->Pattrib); } void VSIdraw(VSIwn,x,y,a,len,c) int VSIwn, x,y, a, len; char *c; { int x2,y2, offset; if(!VSIclip(&x,&y,&x2,&y2,&len,&offset)) RSdraw(VSIwn,x,y,a,len,c+offset); }