home *** CD-ROM | disk | FTP | other *** search
- #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(maxscreens) - 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
- * 2.3 900630 NCSA Telnet 2.3 -QAK
- *
- */
-
- extern int console_file_wanted; /* Flab for whether console should be written
- * to c:\tmp\console.fil also */
- #define VSMASTER
-
- #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 "vsinit.h"
- #include "externs.h"
-
- #ifdef DEBUGCGW
- int VSckconsist(int out, int verbose);
- #endif
-
-
- 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)))==NULL)
- return(-2);
- for(i=0; i<max; i++) {
- VSscreens[i].loc=NULL;
- VSscreens[i].stat=0;
- }
-
- if (console_file_wanted)
- unlink("c:/tmp/console.fil");
-
- return(0);
- }
-
- VSscrn *VSwhereis(i)
- int i;
- {
- VSvalids(i);
- return(VSIw);
- }
-
- int VSnewscreen(maxlines,screensave,maxwid,IDC)
- int maxwid,maxlines,screensave,IDC;
- {
- int i;
- VSline *tt,*last;
-
- 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==NULL)
- return(-7);
- }
- else
- if((VSscreens[VSIwn].loc=VSIw=(VSscrn *)malloc(sizeof(VSscrn)))==NULL) {
- VSscreens[VSIwn].loc=NULL;
- return(-2);
- }
- if(VSscreens[VSIwn].stat!=2) {
- VSIw->maxlines=maxlines;
- VSIw->numlines=VSDEFLINES;
- }
- VSIw->maxwidth=maxwid-1;
- VSIw->allwidth=maxwid-1;
- VSIw->savelines=screensave;
- VSIw->attrib=0;
- 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->IRM=0;
- VSIw->escflg=0;
- VSIw->top=0;
- VSIw->bottom=23;
- VSIw->parmptr=0;
- VSIw->Rtop=0;
- VSIw->Rleft=0;
- VSIw->Rright=79;
- VSIw->Rbottom=23;
- VSIw->ESscroll=1;
- VSIw->lines=23;
- if((VSIw->linest=(VSline **)malloc(sizeof(VSline *)*(VSIw->lines+1)))==NULL)
- return(-2);
- if((VSIw->attrst=(VSline **)malloc(sizeof(VSline *)*(VSIw->lines+1)))==NULL) {
- free(VSIw->linest);
- return(-2);
- } /* end if */
- VSinuse++;
- if(VSscreens[VSIwn].stat==2) {
- VSscreens[VSIwn].stat=1;
- VSiclrbuf();
- VSItabinit();
- return(VSIwn);
- } /* end if */
- VSscreens[VSIwn].stat=1;
- if((VSIw->tabs=(char *)malloc(maxwid))==NULL) {
- free(VSIw->linest);
- free(VSIw->attrst);
- return(-2);
- } /* end if */
- if((VSIw->buftop=last=(VSline *)malloc(sizeof(VSline)))==NULL) {
- free(VSIw->linest);
- free(VSIw->attrst);
- free(VSIw->tabs);
- return(-2);
- } /* end if */
- if((last->text=(char *)malloc(maxwid))==NULL) {
- free(VSIw->linest);
- free(VSIw->attrst);
- free(VSIw->tabs);
- free(VSIw->buftop);
- return(-2);
- } /* end if */
- memset(last->text,' ',maxwid); /* clear line to blanks */
- last->next=NULL;
- last->prev=NULL;
- for(i=0; i<=(VSPBOTTOM+VSDEFLINES); i++) {
- tt=(VSline *)malloc(sizeof(VSline));
- if(tt==NULL || (tt->text=(char *)malloc(maxwid))==NULL)
- return(-2);
- memset(tt->text,' ',maxwid); /* clear line to blanks */
- tt->next=NULL;
- tt->prev=last;
- last->next=tt;
- last=tt;
- }
- VSIw->scrntop=last;
- for(i=VSPBOTTOM; i>0; i--)
- VSIw->scrntop=VSIw->scrntop->prev; /* Go to right place... */
- VSIw->attrst[0]=last=(VSline *)malloc(sizeof(VSline));
- if(last==NULL || (last->text=(char *)malloc(maxwid))==NULL)
- return(-2);
- memset(last->text,0,maxwid); /* clear attributes to none */
- last->next=NULL;
- last->prev=NULL;
- for(i=0; i<=VSPBOTTOM; i++) {
- tt=(VSline *)malloc(sizeof(VSline));
- if(tt==NULL || (tt->text=(char *)malloc(maxwid))==NULL)
- return(-2);
- memset(tt->text,0,maxwid); /* clear attributes to none */
- tt->next=NULL;
- tt->prev=last;
- last->next=tt;
- last=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];
- #ifdef OLD_WAY
- VSiclrbuf();
- #endif
- VSItabinit();
- VSIw->vistop=VSIw->scrntop;
- if(VSIw->linest[VSPBOTTOM]->next!=NULL)
- return(-42);
- #ifdef DEBUGCGW
- VSckconsist(1,1);
- #endif
- return(VSIwn);
- }
-
- int VSdestroy(w)
- int w;
- {
- VSline *p,*oldp;
-
- if(VSvalids(w)!=0)
- return(-3);
- p=VSIw->attrst[0];
- do {
- free(p->text);
- oldp=p;
- p=p->next;
- free(oldp);
- } while((p!=NULL) && (p!=VSIw->attrst[0]));
- p=VSIw->buftop;
- do {
- free(p->text);
- oldp=p;
- p=p->next;
- free(oldp);
- } while((p!=NULL) && (p!=VSIw->buftop));
- free(VSIw->tabs);
- free(VSIw);
- VSscreens[w].stat=0;
- VSIwn=-1;
- VSinuse--; /* SCA '87 */
- return(0);
- }
-
- #ifdef DEBUGCGW
- int VSckconsist(out,verbose)
- int out,verbose;
-
- #endif
-
- #ifdef DEBUGPC
- int VSckconsist(out,verbose)
- int out,verbose;
- {
- VSline *topa,*topt,*a,*t;
- int line, i;
- char tmpstr[256];
-
- for(i=0; i<VSmax; i++) { /* For all possible screens... */
- switch(VSscreens[i].stat) {
- case 0:
- if(out&&verbose) {
- sprintf(tmpstr,"Screen %d inactive\n",i);
- vprint(console->vs,tmpstr);
- }
- break;
-
- case 1:
- if(out) {
- sprintf(tmpstr,"Screen %d active\n",i);
- vprint(console->vs,tmpstr);
- }
- 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) {
- sprintf(tmpstr," Attrib thinks its circular\n");
- vprint(console->vs,tmpstr);
- }
- if(topa!=VSIw->attrst[VSPBOTTOM]) {
- sprintf(tmpstr,"***********BUT IT'S NOT*************\n");
- vprint(console->vs,tmpstr);
- }
- for(line=1; line<=VSPBOTTOM; line++) {
- if(a!=VSIw->attrst[ line]) {
- if(out) {
- sprintf(tmpstr," Attrib line %d is wrong !\n", line);
- vprint(console->vs,tmpstr);
- }
- else
- return(-1);
- }
- a=a->next;
- if(!a) {
- if(out) {
- sprintf(tmpstr," Attrib line %d is NULL\n", line);
- vprint(console->vs,tmpstr);
- }
- else
- if(!out&&line!=VSPBOTTOM)
- return(-2);
- }
- }
- if(topt&&out) {
- sprintf(tmpstr," Linest thinks its circular\n");
- vprint(console->vs,tmpstr);
- }
- if(VSIw->linest[VSPBOTTOM]->next) {
- sprintf(tmpstr," More than VSPBOTTOM lines.... \n");
- vprint(console->vs,tmpstr);
- }
- for(line=1; line<=VSPBOTTOM; line++) {
- if(t!=VSIw->linest[ line]) {
- if(out) {
- sprintf(tmpstr," Linest line %d is wrong !\n", line);
- vprint(console->vs,tmpstr);
- }
- else
- return (-3);
- }
- t=t->next;
- if(!t) {
- if(out) {
- sprintf(tmpstr," Linest line %d is NULL\n", line);
- vprint(console->vs,tmpstr);
- }
- else
- if(line!=VSPBOTTOM)
- return(-4);
- }
- }
- if(VSIw->numlines>0) {
- if(out) {
- sprintf(tmpstr," Thinks that there is scrollback of %d lines ", VSIw->numlines);
- vprint(console->vs,tmpstr);
- }
- t=VSIw->linest[VSPBOTTOM]->next;
- line=0;
- while(t!=NULL && t!=VSIw->buftop) {
- t=t->next;
- line++;
- }
- if(out) {
- sprintf(tmpstr," [ Actual is %d ]\n", line);
- vprint(console->vs,tmpstr);
- }
- if(out&&t==NULL) {
- sprintf(tmpstr," Lines end in a null\n");
- vprint(console->vs,tmpstr);
- }
- if(out&&t==VSIw->buftop) {
- sprintf(tmpstr," Lines end in a wraparound\n");
- vprint(console->vs,tmpstr);
- }
- }
- else
- if(out) {
- sprintf(tmpstr," There is no scrollback");
- vprint(console->vs,tmpstr);
- }
- break;
-
- case 2:
- if(out&&verbose) {
- sprintf(tmpstr,"Screen %d detached\n",i);
- vprint(console->vs,tmpstr);
- }
- break;
-
- default:
- if(out) {
- sprintf(tmpstr,"Screen %d invalid stat\n",i);
- vprint(console->vs,tmpstr);
- }
- break;
-
- }
- }
- return(0);
- }
- #endif
-
- #ifdef USEDETATCH
- VSdetatch(w)
- int w;
- {
- if(VSscreens[w].stat!=1)
- return(-1);
- VSscreens[w].stat=2;
- VSIwn=-1;
- VSinuse--; /* SCA '87 */
- }
- #else
-
- void VSdetatch(w)
- int w;
- {
- VSdestroy(w);
- }
- #endif
-
- void VSiclrbuf(void )
- {
- int j,i;
- 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++=' ';
- }
- }
- }
-
- int VSredraw(w,x1,y1,x2,y2)
- int w,x1,y1,x2,y2;
- {
- char *pt,*pa;
- int cc,cm;
- char lc,la;
- VSline *yp;
- 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->maxlines)
- y2=-VSIw->maxlines;
- if(y1<-VSIw->maxlines)
- y1=-VSIw->maxlines;
- 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);
- }
-
- int 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 */
- if (console_file_wanted)
- if (w == console->vs) {
- FILE *console_file;
- if ((console_file = fopen("c:/tmp/console.fil","a")) != NULL) {
- fwrite(ptr, 1, len-1, console_file);
- fclose(console_file);
- }
- }
- return(0);
- }
-
- int 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);
- }
-
- int 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 */
- }
- return(0);
- }
-
- int 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;
-
- if(VSvalids(w)!=0)
- return(-3);
- if(k<VSUP) { /* not a character which we handle (shouldn't even get here) */
- RSsendstring(w,&k,1);
- if(echo)
- VSwrite(w,&k,1);
- return(0);
- }
- if((k>VSLT) && (k<VSF1) && (!VSIw->DECPAM)) { /* send keypad codes */
- 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);
- }
- #ifdef QAK
- if(k>=VSUP_SPECIAL) {
- vskptr=VSkban; /* prefix for arrow keys */
- k-=64; /* decrement the key back to the proper range of values */
- } /* end if */
- else
- #endif
- if(VSIw->DECPAM && VSIw->DECCKM) /* prefix aux keypad keys */
- vskptr=VSkbax;
- else
- if(k<VSK0) /* prefix normal arrow keys */
- vskptr=VSkban;
- else
- if(k<VSF1) /* prefix for keypad normal */
- vskptr=VSkbkn;
- else /* prefix for function keys */
- vskptr=VSkbfn;
- vskptr[2]=VSIkpxlate[1][k-VSUP];
- RSsendstring(w,vskptr,3);
- if(echo)
- VSwrite(w,vskptr,3);
- return(0);
- }
-
- int VSclearall(w)
- int w;
- {
- if(VSvalids(w)!=0)
- return(-3);
- return(0);
- }
-
- int 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 */
- }
-
- int 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);
- }
-
- int VSscrolback(w,in)
- int w,in;
- {
- int sn,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==NULL)
- DEBUGGER();
- #endif
- 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);
- }
-
- int VSscrolforward(w,n)
- int w,n;
- {
- int sn;
-
- 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);
- }
-
- int VSscrolright(w,n)
- int w,n;
- {
- int sn,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(0); /* 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);
- }
-
- int VSscrolleft(w,n)
- int w,n;
- {
- int sn,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(0); /* 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);
- return(0);
- }
-
- int VSscrolcontrol(w,scrolon, offtop)
- int w,scrolon,offtop;
- {
- if(VSvalids(w)!=0)
- return(-3);
- if(scrolon>-1)
- VSIw->savelines=scrolon;
- if(offtop>-1)
- VSIw->ESscroll=offtop;
- return(0);
- }
-
- int 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);
- }
-
- int VSsnapshot(w)
- int w;
- {
- if(VSvalids(w)!=0)
- return(-3);
- return(0);
- }
-
- int VSvalids(w)
- int w;
- {
- if(VSinuse==0)
- return(-5); /* -5=no ports in use */
- if((w>VSmax) || (w<0))
- return(-6); /* blown out the top of the stuff */
- if(VSIwn==w)
- return(0); /* Currently set to that window */
- VSIwn=w;
- if(VSscreens[w].stat!=1)
- return(-3);/* not currently active */
- VSIw=VSscreens[w].loc;
- if(VSIw==NULL)
- return(-4); /* no space allocated */
- return(0);
- }
-
- int VSmaxwidth(w)
- int w;
- {
- if(VSvalids(w)!=0)
- return(-3);
- return(VSIw->maxwidth);
- }
-
- VSline *VSIGetLineStart(w,y1)
- int 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 lx,ly, /* Upper bounds of selection */
- ux,uy; /* Lower bounds of selection */
- int maxwid;
- char *origcp;
- VSline *t;
-
- if(VSvalids(w)!=0)
- return(-3);
- 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 */
- if ((long)(lx-ux) < max)
- charp=VSIstrcopy(&t->text[ux+1], lx-ux, charp, table);
- else
- charp=VSIstrcopy(&t->text[ux+1], (int)(max - (long)(charp-origcp)), 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);
- if(((long)(maxwid-ux) < max))
- charp=VSIstrcopy(&t->text[ux+1],maxwid-ux,charp,table);
- else
- charp=VSIstrcopy(&t->text[ux+1],(int) (max-(long)(charp-origcp)),charp,table);
- *charp++=*EOLS;
- uy++;
- t=t->next;
- while(uy<ly&&uy<VSPBOTTOM) {
- if((long)(maxwid+1) < max)
- charp=VSIstrcopy(t->text,maxwid+1,charp,table);
- else
- charp=VSIstrcopy(t->text,(int)(max - (long) (charp-origcp)),charp, table);
- *charp++=*EOLS;
- t=t->next;
- uy++;
- }
- if(ly>VSPBOTTOM)
- lx=maxwid;
- if((long)(lx+1) < max)
- charp=VSIstrcopy(t->text,lx+1,charp,table);
- else
- charp=VSIstrcopy(t->text,(int)(max - (long)(charp-origcp)),charp,table);
- if(lx>=maxwid)
- *charp++=*EOLS;
- }
- return((long)(charp - origcp) );
- }
-
- int VSgtlines(w)
- int w;
- {
- if(VSvalids(w)!=0)
- return(-3);
- return(VSIw->lines+1);
- }
-
- int VSsetlines(w,lines)
- int w,lines;
- {
- VSline **attrst,**linest; /* For storage of old ones */
- int i,offset;
-
- if(VSvalids(w)!=0)
- return(-3);
- lines-=1; /* Correct for internal use */
- if(lines==VSIw->lines)
- return(0);
- attrst=VSIw->attrst; /* Save previous line pointers */
- linest=VSIw->linest;
- if((VSIw->linest=(VSline **)malloc(sizeof(VSline *)*(lines+1)))==NULL)
- return(-1);
- if((VSIw->attrst=(VSline **)malloc(sizeof(VSline *)*(lines+1)))==NULL)
- return(-1);
- if(lines<VSIw->lines) {
- offset=VSIw->lines-lines;
- VSIw->numlines+=offset; /* That stuff is now scrollback */
- VSIw->scrntop=linest[offset]; /* Move the top of the screen */
- VSIw->vistop=VSIw->scrntop; /* Force a move to the top of the screen */
- attrst[offset]->prev=attrst[VSIw->lines]; /* Make attr circ. */
- attrst[VSIw->lines]->next=attrst[offset];
- for(i=0; i<offset; i++) {
- free(attrst[i]->text); /* Free attribute data */
- free(attrst[i]); /* and header */
- }
- VSIw->lines=lines;
- VSIlistndx(VSIw->scrntop,attrst[offset]); /* Re-sync the indices */
- }
- else {
- for(i=0; i<=VSIw->lines; i++) { /* Get old Attribute lines */
- VSIw->attrst[i]=attrst[i]; /* and text lines */
- VSIw->linest[i]=linest[i];
- }
- for(i=VSIw->lines; i<lines; i++) {
- VSIw->attrst[i+1]=VSInewline(); /* Make new attribute lines */
- VSIw->attrst[i]->next=VSIw->attrst[i+1];
- VSIw->attrst[i+1]->prev=VSIw->attrst[i];
- VSIw->linest[i+1]=VSInewline(); /* Make new text lines */
- VSIw->linest[i]->next=VSIw->linest[i+1];
- VSIw->linest[i+1]->prev=VSIw->linest[i];
- memset(VSIw->linest[i+1]->text,' ',VSIw->allwidth+1);
- memset(VSIw->attrst[i+1]->text,' ',VSIw->allwidth+1);
- #ifdef OLD_WAY
- tempa=VSIw->attrst[i+1]->text; /* Clear out this line */
- temp =VSIw->linest[i+1]->text;
- for(j=0; j<=VSIw->allwidth; j++) {
- *temp++=' ';
- *tempa++=0;
- }
- #endif
- }
- VSIw->attrst[0]->prev=VSIw->attrst[lines]; /* Make attr circ. */
- VSIw->attrst[lines]->next=VSIw->attrst[0];
- VSIw->linest[lines]->next=NULL; /* for the last line of text only */
- VSIw->lines=lines;
- VSIlistndx(VSIw->scrntop,VSIw->attrst[0]); /* Re-sync the indices */
- }
- VSIw->top=0;
- VSIw->bottom=lines;
- VSIw->Rtop=lines-(VSIw->Rbottom-VSIw->Rtop);
- VSIw->Rbottom=lines;
- if(VSIw->Rtop>=0)
- VSIw->vistop=VSIw->linest[VSIw->Rtop];
- else {
- int n=-VSIw->Rtop;
- VSIw->vistop=VSIw->linest[ 0];
- while(n--)
- VSIw->vistop=VSIw->vistop->prev;
- }
- free(attrst); /* Nuke the previous pointers */
- free(linest);
- RSbufinfo(w,VSIw->numlines,VSIw->Rtop,VSIw->Rbottom);
- return(VSIw->lines);
- }
-