📄 eedisp.c
字号:
if (dspf & RD_REDO) { s->sl_flg |= SL_REDO; /* Do "fast update" */ goto nodel; /* Just go update line */ }#endif /*IMAGEN*/ if((trm_flags&TF_IDLIN)==0) goto nodel; /* Just go update line */ /* Check for I/D line. If no hints exist, check for both * insert and delete. */ if((dspf&(RD_ILIN|RD_DLIN))==0) dspf |= RD_ILIN|RD_DLIN; noicost = 0; nodcost = 0; /* Check for insert line. See if the current old screen * line is duplicated among any of the new lines which * follow it. If a match is found, keep looking and add * up the number of characters in the matching lines. */ if(dspf&RD_ILIN) { /* See if this old screen line is needed elsewhere */ if(s->sl_col == 0) /* Ignore if blank */ goto noins; for(n = i+1; n < bot; n++) { if((scr[n]->sl_flg&SL_MOD)==0) break; if(slineq(s, scr[n])) /* Old, new */ { if(!noicost) iline = n; /* 1st time */ noicost += s->sl_col; s++; } else if(noicost) break; } if(!noicost) /* If no match, forget it */ goto noins; /* S will not have changed. */ s = scr[i]; /* Restore S */ n = iline; /* Have matches, get index * of first matching line */ /* Heuristic to decide whether to perform * insert-line operation. Kind of stupid, but * good enough for now. */ num = (n-i)*(tvc_ldn+tvc_lin) + (tvc_li + tvc_ld); if((n-i) >= (scr_ht-(ECHOLINES+3)) /* Don't move lines all the * way down full screen! */ || num >= noicost) /* Compare cost with estimated * cost of not doing insert.*/ goto noins; /* Insert lines! */ dspf &= ~RD_ILIN; inslin(i, n - i, w); for(; i < n; i++) /* Update intervening lines */ upd_line (i); goto ldone; }noins: /* Check for delete line. See if the new screen line * is duplicated among any of the old lines already on * the screen. If a match is found, keep looking and add * up the number of characters in the matching lines. */ if(dspf&RD_DLIN) { /* See if the new line already exists elsewhere */ if(s->sl_ncol == 0) /* Ignore blank lines */ goto nodel; for (n = i + 1; n < bot; n++) { if((scr[n]->sl_flg&SL_MOD)==0) break; if(slineq(scr[n],s)) /* Old, new */ { if(!nodcost) dline = n; /* 1st time */ nodcost += s->sl_ncol; s++; } else if(nodcost) break; } if(!nodcost) /* If no match, forget it */ goto nodel; /* S will not have changed. */ s = scr[i]; /* Restore S */ n = dline; /* Index of 1st match */ /* Heuristic to decide whether to perform * delete-line operation. Same hack as for * insert-line. */ num = (n-i)*(tvc_ldn+tvc_lin) + (tvc_li + tvc_ld); if((n-i) >= (scr_ht-(ECHOLINES+3)) || num >= nodcost) goto nodel; /* Delete lines! */ dspf &= ~RD_DLIN; dellin(i, n - i, w); goto ldone; }nodel: /* All failed, so just update line */ upd_line(i);ldone: s->sl_flg &= ~SL_MOD; /* Clear mod flag */ }done:#if FX_SOWIND t_dostandout(oldso); /* Back to previous mode */#endifzdone: w->w_redp = 0; return(0); /* Say completed */}/* * SLINEQ - Compare old, new screen image lines. If new line doesn't * have the modified flag set, use its old image. * If the standout mode differs, always fails. */slineq(olds, news)struct scr_line *olds;struct scr_line *news;{ register char *cpo, *cpn; register int cnt; cpo = (char *)news; if(((struct scr_line *)cpo)->sl_flg&SL_MOD) { cnt = ((struct scr_line *)cpo)->sl_ncol; cpn = ((struct scr_line *)cpo)->sl_nlin;#if FX_SOWIND /* Mode of old must match mode of new */ if(((olds->sl_flg & SL_CSO)==0) != ((((struct scr_line *)cpo)->sl_flg & SL_NSO)==0)) return 0;#endif } else { cnt = ((struct scr_line *)cpo)->sl_col; cpn = ((struct scr_line *)cpo)->sl_line;#if FX_SOWIND /* Modes of current lines must match */ if((olds->sl_flg & SL_CSO) != (((struct scr_line *)cpo)->sl_flg & SL_CSO)) return 0;#endif } /* Crufty match stuff */ if(cnt != olds->sl_col) return(0); if(cnt) { cpo = olds->sl_line; do { if(*cpo++ != *cpn++) return(0); } while(--cnt); } return(1);}/* UPD_LINE(lineno) - Effects the update of a physical screen line, * assuming that the screen line structure for that line has been * properly set up by fix_wind. It cannot be interrupted by typein. * Does a lot of work to check out optimization for char I/D. * Someday it could also check out the possibility of doing a CLEOL at * some point to reduce the number of spaces that need to be output. */upd_line(y)int y;{ register i; register char *sci, *cp; struct scr_line *s; int xpos; /* actual screen position */ int c, c2, p2, cmpcost, delcost; int savc, ocol, ncol; char *savcp, *savsci;#if FX_SOWIND int oldso, newso; int writall = 0;#endif s = scr[y]; savsci = sci = s->sl_line; /* What is currently on the screen */#if IMAGEN if (s->sl_flg & SL_REDO) { /* Check for line-redo flag */ s->sl_flg &= ~SL_REDO; /* Clear it: we are handling it */ writall = 1; /* Re-do this line completely */ t_move(y, 0); t_docleol(); s->sl_col = 0; }#endif /*IMAGEN*/#if FX_SOWIND /* See whether modes of the lines are the same or not. */ newso = (s->sl_flg & SL_NSO)!=0; /* Get new mode (true if SO)*/ if(((s->sl_flg & SL_CSO)!=0) != newso) { t_move(y, 0); /* Not same, must zap existing line */ t_docleol(); s->sl_col = 0; writall = newso; /* Output all if SO is new mode */ } oldso = t_dostandout(newso); /* Get in right mode */#endif ocol = s->sl_col; savcp = cp = s->sl_nlin; ncol = s->sl_ncol; /* Find leading equalness */ i = ocol; if(i > ncol) i = ncol; /* Use minimum count */ if(i) { do { if(*cp++ != *sci++) { --cp; break; } } while(--i); i = cp - savcp; sci = savsci; /* Restore ptr to beg of cur line */ } /* From here on, "i" is now the x-coordinate (column addr) * of the first position that doesn't match. "cp" points to * the first nonmatching char in the new line image. */#if COHERENT /* Has direct video interface capability */ if(trm_flags&TF_DIRVID) { if(ncol < ocol) { /* Flesh out new line to completely replace old */ fillsp(&s->sl_nlin[ncol], ocol-ncol); ncol = ocol; } /* Spit out changed stuff. t_direct will handle the * case where i == ncol (ie no changes needed). */ t_direct(y,i,cp,ncol-i); goto done; }#endif /*COHERENT*/ if(i == ncol) /* Matched up to end of new line? */ goto idone; /* Yes, can skip big loop! */#if FX_SOWIND if(writall) /* If simply writing everything...*/ { t_move(y, 0); tputn(cp, ncol); /* Output them all */ curs_col = ncol; /* Update cursor position */ goto idone; /* then wrap up! */ }#endif /* Now must fill out remainder of old line with blanks. */ if(ocol < scr_wid) {#if FX_SOWIND if(newso) fillset(&sci[ocol], scr_wid-ocol, 0); else#endif fillsp(&sci[ocol],scr_wid-ocol); /* Fill out */ } /****** Main update loop. ******/ for (; i < ncol; i++) { c = *cp++; /* Note *CP will point to next */ if(c == sci[i]) continue; if(i >= ocol) /* Past EOL of old line? */ {putin: sci[i] = c; if(y != curs_lin || i != curs_col) t_move(y, i); tput(c); curs_col++; continue; } if((trm_flags&TF_IDCHR)==0) /* Replace */ goto putin; /* Do checking to see whether char I/D operations should * be invoked. This code is quite CPU intensive and * can cause noticeable pauses if run on a slow CPU with * a fast (9600) terminal line. The optimization tradeoff * seems worthwhile most of the time, however. */ cmpcost = 0; /* Default is don't compare */ if(ncol == ocol) /* If line lengths same, must chk */ {/* if(ncol >= scr_wid) */ /* If line overrun, compare */ cmpcost++; }#if 0If ncol == ocol, have problem with tabs: If don''t use I/D char, but tabs exist, lots of wasteful update. If DO use I/D char, and no tabs exist, potential for mistakenly using I/D when didn''t have to. Not too bad, though? If DO use I/D char, then mild screw when inserting/deleting just before a tab, since could have just overwritten, but I/D insists on jerking things around. Insert test: If old char was space, replace? Problem: will cause cursor jump if really should have shifted a long run of spaces. But that is probably okay. Delete test: If new char is space, replace? again, will cause cursor jump with long run of spaces.#endif /*COMMENT*/ if(ncol < ocol || cmpcost) /* Try delete-char */ { /* Search old for match of c and nextc */dodel: savc = c; if(i >= ncol-1) goto putin; c2 = *cp; if(c == SP && ncol == ocol) goto tryins; p2 = i; for(;;) { if(c == sci[i] && c2 == sci[i+1]) break; if(++i < ocol) continue; i = p2; if(cmpcost) {cmpcost = 0; goto tryins;} goto putin; } /* Find # chars that match (i.e. will be saved) */ for(c=1; (i+c < ncol) && (sci[i+c] == cp[c-1]); c++); delcost = tvc_cd + tvc_cdn*(i - p2); if(delcost >= c) { c = savc; i = p2; if(cmpcost) { cmpcost = 0; goto tryins;} goto putin; /* Punt */ } if(cmpcost) { c = savc; i = p2; goto tryins; } t_move(y, p2); c = i - p2; /* Find # chars to flush */ strncpy(&sci[p2],&sci[i], ocol-i); ocol -= c; fillsp(&sci[ocol], c); i = p2; /* Restore i */ t_delchr(c); /* Flush this many cols */ continue; } /* Try ins-char */ /* Search new for match of i and i+1 */ /* Note this cannot be used while in standout mode, since ** the new spaces created will probably be in the wrong mode. */tryins:#if FX_SOWIND if(newso) goto putin;#endif if(i+1 >= ocol) goto putin; savc = c; savcp = cp; c2 = sci[i+1]; if(sci[i] == SP && ncol == ocol) goto putin; xpos = i; /* save current col */ i++; for(;;) { if(i >= ncol) goto puntx; c = *cp++;inlp2: if(c != sci[xpos]) { if(i > scr_wid) goto puntx; i++; continue; } if(i >= ncol) goto puntx; c = *cp++; if(c != c2) { i++; /* Allow for previous c */ goto inlp2; /* which is always 1 */ } break; } if(i >= scr_wid) goto puntx; /* Find how many chars match (i.e. will be saved) */ for(c = 2; xpos+c < ncol && sci[xpos+c] == *cp++; c++); if((p2 = tvc_ci + tvc_cin*(i - xpos)) >= c) goto puntx; /* Not worth it... */ if(cmpcost && p2 >= delcost) goto puntx; /* Do delchr instead */ /* We've decided to insert some chars! */ i -= xpos; /* Get # char positions to insert */ cp = savcp; /* Get ptr to newline string */ --cp; /* Point at 1st char to insert */ /* Make room in scr array */ inspc(&sci[xpos], &sci[(ocol+i >= scr_wid) ? scr_wid-i : ocol], i); ocol += i; /* Update size of old line */ strncpy(&sci[xpos], cp, i); /* Copy all inserted chars */ t_move(y, xpos); /* Now ensure in right place */ t_inschr(i, cp); /* and insert string onto screen! */ cp += i; /* Update source ptr */ cp++; /* Point to next char */ i += xpos; continue; /* Now continue loop! */ puntx: i = xpos; c = savc; cp = savcp; if(cmpcost) { cmpcost = 0; goto dodel;} goto putin; } /* All done putting up new stuff. Now see if any remaining old ** stuff needs to be cleared from end of line. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -