#include "ded.h" #include "char.h" /* to allow for differing screen sizes, ded must * allocate its own store */ char *curr_break 0, *curr_lim 0; char *my_alloc(size) { register char *res, *new; if ( (new = curr_break+size) > curr_lim) { res = (size-(curr_lim-curr_break)+1024) & (~ 1023); if ( (new = sbrk(res)) == -1) editerror("no more room (my_alloc)"); else { curr_lim = new+res; if (curr_break==0) curr_break = new; new = curr_break+size; } } res = curr_break; curr_break = new; return(res); } char **newscreen() { register char **res, *map; register int row; int width; res = my_alloc(nrows*2); width = (ncols+2) & (~ 1); if (dbug('o')) editerror("nrows is %d, ncols is %d, width is %d", nrows, ncols, width); map = my_alloc(nrows*width); /* set pointers in map */ for (row=0; row<nrows; row++) res[row] = map+row*width; return(res); } setupscreen() { clearscreen(); refreshscreen(); } refreshscreen() { register int row; char lbuf[ENOUGH]; /* display file contents */ for (row=0; row<=LASTINROW; row++) { getfline(topl+row,lbuf); redraw(row,0,lbuf); } showedit(); ttyflush(); } clearscreen() { register int row, col; register char *rm; int width; clear(); /* store spaces in screen map */ if (rowmap==0) editerror("screen map not yet set up (clearscreen)"); for (row=0; row<=FOOTROW; row++) { rm = rowmap[row]; for (col=0; col<=ncols-1; col++) *rm++ = c_SPACE; } } char *copyrow(srow,scol,buf) int srow, scol; char *buf; { register char *pmap, *pbuf; register int count; pmap = rowmap[srow]+scol; if ( (pbuf = buf)==0 ) editerror("row not set up (copyrow)"); count = lastcol(srow)-scol+1; while (count-- > 0) *pbuf++ = *pmap++; *pbuf = 0; } /* insert a row AFTER screen row srow. * this must be done so that the data on screen moves * (in order that the user can see that the insert really has occurred) * and also so that the minimum number of characters are transferred */ ins_row(srow,buffer,pos) int srow; char *buffer; struct CURSOR *pos; { register int i, reg_row; struct CURSOR tmp; reg_row = srow; if (reg_row<=2 || reg_row<LASTINROW && (reg_row<firstrow() || charsin(0,reg_row)>charsin(reg_row+1,LASTINROW)) ) /* top rows stay on screen - just pull lower lines * down one */ { saverow(LASTINROW); if (ttytype==hazeltine) { saveedit(); forcedown(reg_row+1); showedit(); } else for (i=LASTINROW; i>reg_row+1; i--) redraw(i,0,rowmap[i-1]); if (pos->row>reg_row && pos->row<LASTINROW) pos->row++; } else /* make room by pushing top row off screen - there * are two ways of doing this */ { if ( ttytype==hazeltine || charsin(reg_row+1,FOOTROW)<charsin(0,reg_row) ) /* roll up screen, and pull lower lines down one */ { saveedit(); rollup(1); if (ttytype==hazeltine) forcedown(reg_row); else { showedit(); for (i=LASTINROW; i>reg_row; i--) redraw(i,0,rowmap[i-1]); } } else /* push top rows up one position */ { saverow(0); inc_topl(); for (i=0; i<reg_row; i++) redraw(i,0,rowmap[i+1]); } if (pos->row<=reg_row && pos->row>0) pos->row--; reg_row--; } shuffile(topl+reg_row+1,1); redraw(reg_row+1,0,buffer); } /* delete a screen row - as above this should usually * involve moving the picture somewhat */ del_row(srow,pos) int srow; struct CURSOR *pos; { register int i, reg_row; char linebuf[ENOUGH]; struct CURSOR tmp; reg_row=srow; if (topl!=0 && (reg_row<=firstrow() ? !emptyline(topl-1) || (reg_row>lastrow() && topl+LASTINROW>=maxl) : topl+LASTINROW>=maxl || (reg_row>=lastrow() ? emptyline(topl+LASTINROW+1) : (ttytype==itt && charsin(0,reg_row-1)<charsin(reg_row+1,LASTINROW))) )) /* pull the top lines down */ { for (i=reg_row; i>=0; i--) { getline(topl+i-1,linebuf); redraw(i,0,linebuf); } if (pos->row<=reg_row && pos->row<LASTINROW) pos->row++; shuffile(topl+reg_row+1,-1); topl--; } else /* pull the bottom lines up */ { while (topl+LASTINROW>=maxl) inc_maxl(); if (ttytype==hazeltine) { saveedit(); forceup(reg_row); getline(topl+LASTINROW+1, linebuf); redraw(LASTINROW, 0, linebuf); showedit(); } else for (i=reg_row; i<=LASTINROW; i++) { getline(topl+i+1,linebuf); redraw(i,0,linebuf); } if (pos->row>reg_row && pos->row>0) pos->row--; shuffile(topl+reg_row+1,-1); } } /* contents of editrow - saved by saveedit etc. */ char erow[ENOUGH]; /* two functions to help when rolling about the screen */ saveedit() { copyrow(EDITROW,0,erow); } showedit() { redraw(EDITROW,0,erow); ttyflush(); } clear() { switch (ttytype) { case itt: ttyout(c_CLEAR); break; case hazeltine: ttyout(c_LEADIN); ttyout('\034'); break; case VC404: ttyout('\030'); ttyout('\014'); /* for screen clear delay */ break; case T1061: ttyout('\014'); break; default: editerror("tty type not set up (clear)"); } real_c.row = real_c.col = 0; } /* looks at the screen row srow and the file line fline. * If they are different, it rewrites the line. */ int tmp_changed false; saverow(srow) int srow; { char sstr[ENOUGH], fstr[ENOUGH]; copyrow(srow, 0, sstr); /* essential to convert it into a string */ getfline(topl+srow,fstr); if (!streq(sstr, fstr)) { addline(topl+srow, sstr); tmp_changed = true; } } savescreen() { int i; for (i=0; i<=LASTINROW; i++) saverow(i); saveedit(); } /* procedures to help in hardware-scrolling terminals */ forcedown(row) int row; { register int reg_row; struct CURSOR tmp; store_c(&virt_c, &tmp); virt_c.row = reg_row = row; if (ttytype==hazeltine) { fixpos(); ttyout(c_LEADIN); ttyout(04032); /* confuse ttyout */ real_c.col = 0; } else editerror("forcedown on non-hazeltine"); store_c(&tmp, &virt_c); shufscreen(reg_row, FOOTROW, 1); } forceup(row) int row; { register int reg_row; struct CURSOR tmp; store_c(&virt_c, &tmp); virt_c.row = reg_row = row; if (ttytype==hazeltine) { fixpos(); ttyout(c_LEADIN); ttyout(023); real_c.col = 0; } else editerror("forceup on non-hazeltine"); store_c(&tmp, &virt_c); shufscreen(reg_row, FOOTROW, -1); }