/* * SCRLBACK.C **************************************************************************** * * * NCSA Telnet for the PC * * * * National Center for Supercomputing Applications * * 152 Computing Applications Building * * 605 E. Springfield Ave. * * Champaign, IL 61820 * * * * This program is in the public domain. * * * **************************************************************************** * Revisions: * 6-26-90 Separated from look.c by Heeren Pathak */ #ifdef MSC #define mousecl mousecml #endif #ifdef MOUSE #include "mouse.h" #endif #include #include #include #include #include #ifdef MSC #ifdef __TURBOC__ #include #else #include #endif #endif #include "whatami.h" #include "nkeys.h" #include "windat.h" #include "hostform.h" #include "protocol.h" #include "externs.h" static int its_in(long ,long ); extern int scroll, /* which way do we scroll */ cflag, /* are we copying ? */ cbuf, /* do we have things in the buffer? */ mcflag, /* mouse button flag */ vsrow, /* VS row */ numline, mighty; /* mouse present? */ extern long size, /* size of buffer */ cstart, /* starting location of VS copy buffer */ cend, /* ending location of VS copy buffer */ cdist; /* distance to base point */ extern struct config def; extern char *copybuf, *lineend; /***********************************************************************/ /* scrollback * Take keyboard keys to manipulate the screen's scrollback * Written by Heeren Pathak 4/1/89 along with the mouse routinues. */ void scrollback(struct twin *tw) { int row, /* current row */ col, /* current col */ c; /* input */ long i, /* loop index */ temp; /* general purpose */ if(tw->termstate==TEKTYPE) return; set_cur(0); c=n_chkchar(); #ifdef SCRL_MOUSE if(c==-1) { c=chkmouse(); mouse=0; } /* end if */ #endif switch (scroll) { case -1: /* scroll stuff down */ if(c==CURDN || c==PGDN || c==E_CURDN || c==E_PGDN) { scroll=0; c=0; } row=n_row(); col=n_col(); if(vsrow>(-tw->bkscroll)) { /* have not reached limit of buffer */ vsrow--; row=0; VSscrolback(tw->vs,1); temp=4; if(cflag || cbuf) { i=cdist; cdist=(long)(vsrow+row)*80+col; if(cbuf || i>cdist) { temp-=setattr(0,tw->colors[0],tw->colors[2]); temp-=setattr(1,tw->colors[0],tw->colors[2]); } } for(i=0; ivs,1); temp=4; if(cflag || cbuf) { i=cdist; cdist=(long)(vsrow+row)*80+col; if(cbuf || cdist>i) { temp-=setattr(numline-1,tw->colors[0],tw->colors[2]); temp-=setattr(numline,tw->colors[0],tw->colors[2]); } } for(i=0; ivs,-vsrow); vsrow=0; cdist=(long)(row+vsrow)*80+col; n_cur(row,col); if(cflag || cbuf) updatescr(tw->colors[2]); break; case CTRLPGUP: case E_CTRLPGUP: row=col=0; VSscrolback(tw->vs,(tw->bkscroll - vsrow)); vsrow=(-tw->bkscroll); cdist=(long)(row+vsrow)*80+col; n_cur(row,col); if(cflag || cbuf) updatescr(tw->colors[2]); break; case HOME: case E_HOME: row=n_row(); col=n_col(); if(col) { col=0; c=0; } /* end if */ else { row=0; c=1; } /* end else */ cdist=(long)(row+vsrow)*80+col; n_cur(row,col); if(cflag || cbuf) if(c) updatescr(tw->colors[2]); else setattr(row,tw->colors[0],tw->colors[2]); break; case ENDKEY: case E_ENDKEY: row=n_row(); col=n_col(); if(col!=79) { col=79; c=0; } /* end if */ else { row=numline; c=1; } /* end else */ cdist=(long)(row+vsrow)*80+col; if(c) n_cur(numline,col); else n_cur(row,col); if(cflag || cbuf) if(c) updatescr(tw->colors[2]); else setattr(row,tw->colors[0],tw->colors[2]); break; case CURLF: case E_CURLF: row=n_row(); col=n_col(); if(col>0) { col--; cdist=(long)(row+vsrow)*80+col; if(cflag || cbuf) { if(is_in(row,vsrow,col+1)) (*attrptr)(tw->colors[2]); else (*attrptr)(tw->colors[0]); } n_cur(row,col); if(cflag || cbuf) { if(is_in(row,vsrow,col)) (*attrptr)(tw->colors[2]); else (*attrptr)(tw->colors[0]); } } break; case CURRT: case E_CURRT: row=n_row(); col=n_col(); if(col<79) { col++; cdist=(long)(row+vsrow)*80+col; if(cflag || cbuf) { if(is_in(row,vsrow,col-1)) (*attrptr)(tw->colors[2]); else (*attrptr)(tw->colors[0]); } n_cur(row,col); if(cflag || cbuf) { if(is_in(row,vsrow,col)) (*attrptr)(tw->colors[2]); else (*attrptr)(tw->colors[0]); } } break; case CURUP: case E_CURUP: row=n_row(); col=n_col(); if(row>=1) { row--; if(cflag) { cdist=(long)(vsrow+row)*80+col; setattr(row+1,tw->colors[0],tw->colors[2]); setattr(row,tw->colors[0],tw->colors[2]); } } else { if(vsrow>(-tw->bkscroll)) { if (def.autoscroll) scroll=-1; vsrow--; row=0; VSscrolback(tw->vs,1); if(cflag || cbuf) { cdist=(long)(vsrow+row)*80+col; setattr(1,tw->colors[0],tw->colors[2]); setattr(0,tw->colors[0],tw->colors[2]); } } else if(row>0){ row--; if(cflag || cbuf) { cdist=(long)(vsrow+row)*80+col; setattr(row+1,tw->colors[0],tw->colors[2]); setattr(row,tw->colors[0],tw->colors[2]); } } } n_cur(row,col); break; case CURDN: case E_CURDN: row=n_row(); col=n_col(); if(rowcolors[0],tw->colors[2]); setattr(row,tw->colors[0],tw->colors[2]); } } else{ if(vsrow<0) { if (def.autoscroll) scroll=1; ++vsrow; row=numline; VSscrolforward(tw->vs,1); if(cflag || cbuf) { cdist=(long)(vsrow+row)*80+col; setattr(numline-1,tw->colors[0],tw->colors[2]); setattr(numline,tw->colors[0],tw->colors[2]); } } else if(rowcolors[0],tw->colors[2]); setattr(row,tw->colors[0],(int)tw->colors[2]); } } } n_cur(row,col); break; case PGUP: case E_PGUP: row=n_row(); col=n_col(); VSscrolback(tw->vs,numline+1); vsrow-=numline+1; if(vsrow<(-tw->bkscroll)) vsrow=(-tw->bkscroll); cdist=(long)(vsrow+row)*80+col; if(cflag || cbuf) updatescr(tw->colors[2]); n_cur(row,col); break; case PGDN: case E_PGDN: row=n_row(); col=n_col(); VSscrolforward(tw->vs,numline+1); vsrow+=numline+1; if(vsrow>0) vsrow=0; cdist=(long)(vsrow+row)*80+col; if(cflag || cbuf) updatescr(tw->colors[2]); n_cur(row,col); break; case (int)' ': case (int)'\n': row=n_row(); col=n_col(); if(!cflag) { if((n_flags()&3)) { cflag=1; cbuf=0; remark(row,col,vsrow,tw); } else { if(cbuf) resetscr(tw); cflag=1; cbuf=0; cstart=(long)(vsrow+row)*80+col; cdist=cstart; setattr(row,tw->colors[0],tw->colors[2]); } } else { cflag=0; cbuf=1; cend=(long)(vsrow+row)*80+col; } n_cur(row,col); /* Why mark text and not copy it?? rmg 930429 */ if(!cbuf) break; case ALTC: if(cend32700) break; if(copybuf!=NULL) free(copybuf); if((copybuf=(char *)malloc((unsigned int)(size+1)))==NULL) break; #ifdef OLD_WAY size=VSgettext(tw->vs,(int)(cstart%80)-1,(int)(cstart/80),(int)(cend%80),(int)(cend/80),copybuf,size,lineend,0); #else /* Contribution by Hsiao-yang Cheng ++ sycheng@csie.nctu.edu.tw */ /* When we scroll back, the "cstart" and "cend" are negative numbers. In C language, The remainder of a negative number is also a negative number. So the result of VSgettext(...,cstart%80, ...., cend%80,...) will not be the expected result. This also can be fixed in function VSgettext(), but I solve it in scrollback(). */ /* Thanks much, rmg 931111 */ { int t1,t2,t3,t4; t1=(int)(cstart%80); t2=(int)(cstart/80); if (t1<0) { t1+=80; t2--; } t3=(int)(cend%80); t4=(int)(cend/80); if (t3<0) { t3+=80; t4--; } size=VSgettext(tw->vs,t1-1,t2,t3,t4,copybuf,size,lineend,0); } #endif copybuf[size]='\0'; break; default: break; } set_cur(1); } /************************************************* * * setattr() * sets the attribute of a line */ int setattr(int row,int attrn,int attrh) { int i, col; if(is_in(row,vsrow,0) || is_in(row,vsrow,79) || its_in((long)(row+vsrow-1)*80,(long)(row+vsrow+1)*80+79 )) { n_row(); col=n_col(); for(i=0; i<80;i++) { n_cur(row,i); if(is_in(row,vsrow,i)) (*attrptr)((char)attrh); else (*attrptr)((char)attrn); } n_cur(row,col); return(1); } return(0); } /************************************************ * * resetscr(struct twin *tw) * clear marked text from screen */ void resetscr(struct twin *tw) { int row,col,r,c; r=n_row(); c=n_col(); for(row=0; rowcolors[0])); } n_cur(r,c); } /************************************************* * * updatescr() * marks screen */ void updatescr(int attr) { int row, col, r, c; r=n_row(); c=n_col(); for(row=0;row2) return(CURRT); if(m3<-2) return(CURLF); if(m4>2) return(CURDN); if(m4<-2) return(CURUP); #else num_right += m3; num_down += m4; if (abs(num_right)>abs(num_down)) { if(num_right >= MIN_MOVE) { num_right-=MIN_MOVE; return(CURRT); } /* end if */ if(num_right <= -MIN_MOVE) { num_right+=MIN_MOVE; return(CURLF); } /* end if */ } /* end if */ if(num_down >= MIN_MOVE) { num_down-=MIN_MOVE; return(CURDN); } /* end if */ if(num_down <= -MIN_MOVE) { num_down+=MIN_MOVE; return(CURUP); } /* end if */ #endif m1=3; /* read mouse buttons */ mousecl(&m1,&m2,&m3,&m4); if(m2 & 1) m2=1; else m2=0; if(m2!=mcflag) { mcflag=m2; return((int)' '); } return(-1); } #endif #ifndef MOUSE /***************************************************************** * * initmouse() * check to see if we have a mouse */ int initmouse(void ) { int m1=0, m2=0, m3=0, m4=0; /* mouse variables */ m1=0; mousecl(&m1,&m2,&m3,&m4); /* initialize mouse driver */ if(!m1) return(0); m1=2; mousecl(&m1,&m2,&m3,&m4); /* turn off software cursor */ return(1); } #endif /************************************** * * is_in() * check to see if cursor is at marked location */ int is_in(int row,int vs_row,int col) { long vsloc, c, end, start; start=cstart; if(cbuf) end=cend; else if(cflag) end=cdist; else return(0); if(end=vsloc)) return(1); return(0); } /******************************************* * * its_in() * * checks to see if marked area is between two points */ static int its_in(long vsstart,long vsend) { long start,end; start=cstart; if(cbuf) end=cend; else if(cflag) end=cdist; else return(0); if(((vsstart<=start) && (vsend>=start)) || ((vsstart<=end) && (vsend>=end))) return(1); return(0); } /******************************************** * * remark() * * it resets the the end points of the marked text * */ void remark(int row,int col,int vs_row,struct twin *tw) { long vsloc, dstart, dend; int x, y; vsloc=(long)(row+vs_row)*80+col; dstart=vsloc-cstart; dend=vsloc-cend; if(dstart<0) dstart=-dstart; if(dend<0) dend=-dend; if(dstartcolors[2]); } /* end if */ else { n_cur(y,x); (*attrptr)(tw->colors[0]); } /* end else */ } /* end for */ n_cur(row,col); }