📄 ll_refresh.c
字号:
/* Copyright (c) 1984 AT&T *//* All Rights Reserved *//* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T *//* The copyright notice above does not evidence any *//* actual or intended publication of such source code. */#ifndef lintstatic char sccsid[] = "@(#)ll_refresh.c 1.1 92/07/30 SMI"; /* from S5R3 1.4.1.2 */#endif#include "curses.ext"extern int InputPending;extern int outchcount;int didntdobotright; /* writechars didn't output char in bot right corner */static int ll_first, ll_last, ll_clear; /* bounds of area touched */struct line *_line_alloc();/* * Optimally make the screen (which currently looks like SP->cur_body) * look like SP->std_body. If use_idl is 1, this routine will call * out all its horses, including some code to figure out * how to use insert/delete line. If use_idl is 0, or if the terminal * does not have insert/delete line, a simpler scheme will * be used, and the insert/delete line features of the terminal will not * be used. * * While the original intent of this parameter was speed (insert/delete * line was slow) the parameter currently is there to avoid annoying * the user with unnecessary insert/delete lines. */int_ll_refresh (use_idl){ register int n;#ifdef DEBUG if(outf) { fprintf(outf, "_ll_refresh(%d)\n", use_idl); fprintf(outf, "phys cursor at (%d,%d), want it at (%d,%d)\n", SP->phys_y, SP->phys_x, SP->virt_y, SP->virt_x); }#endif if (_ta_check()) return 0; outchcount = 0; /* update soft labels */ { register struct slkdata *SLK = SP->slk; register int i; extern int _outch(); int dooutput; if (SLK && (SLK->fl_changed || SP->doclear)) { dooutput = SLK->window == NULL; if (SP->doclear) for (i = 0; i < 8; i++) { if (dooutput) tputs(tparm(plab_norm, i+1, SLK->label[i]), 1, _outch); SLK->changed[i] = FALSE; strcpy(SLK->scrlabel[i], SLK->label[i]); } else for (i = 0; i < 8; i++) if (SLK->changed[i]) { if (strcmp(SLK->label[i], SLK->scrlabel[i]) != 0) { if (dooutput) tputs(tparm(plab_norm, i+1, SLK->label[i]), 1,_outch); strcpy(SLK->scrlabel[i], SLK->label[i]); } SLK->changed[i] = FALSE; } tputs(label_on, 1, _outch); SLK->fl_changed = FALSE; } }#ifdef DEBUG if (outf) fprintf(outf, "virt cursor at y=%d, x=%d\n", SP->virt_y, SP->virt_x);#endif if (SP->doclear) {#ifdef DEBUG if(outf) fprintf(outf, "SP->doclear, clearing screen\n");#endif _reset (); SP->doclear = 0; for (n = 1; n <= lines; n++) { if (SP->cur_body[n] != SP->std_body[n]) _line_free (SP->cur_body[n]); SP->cur_body[n] = 0; } ll_first = 1; ll_last = lines; } else if (!SP->fl_changed || (_find_bounds(), ll_first > lines)) { if (!InputPending && SP->virt_x >= 0 && SP->virt_y >= 0) _pos(SP->virt_y, SP->virt_x); __cflush(); return outchcount; } _trim_trailing_blanks(); if (magic_cookie_glitch > 0) _toss_cookies();#ifdef DEBUG _refr_dump(use_idl);#endif _check_clreos(); SP->check_input = SP->baud / 2400; /* Choose between two updating algorithms. */ if (ll_first < ll_last && use_idl && _cost(ilfixed) < INFINITY) {#ifdef DEBUG if(outf) fprintf(outf, "use_idl\n");#endif _fix_hash(); _chk_scroll(); _sl_upd(); } else _f_upd(); if (ll_clear > 0) { _pos(ll_clear-1, 0); tputs(clr_eos, 1, _outch); } if (didntdobotright) _fix_bot_right(); if (!ceol_standout_glitch) { _hlmode(0); _sethl(); }#ifdef DEBUG if(outf) fprintf(outf, "at end, phys SP->curptr at (%d,%d), want SP->curptr at (%d,%d)\n", SP->phys_y, SP->phys_x, SP->virt_y, SP->virt_x);#endif if (!InputPending) { if (SP->virt_x >= 0 && SP->virt_y >= 0) _pos (SP->virt_y, SP->virt_x); SP->fl_changed = FALSE; } __cflush();#ifdef DEBUG if(outf) { fprintf(outf, "end of _ll_refresh, InputPending %d\n", InputPending); fflush(outf); }#endif return outchcount;}/* * Find the topmost and bottommost line that has been touched since * the last refresh. After this, we need look no further than these * bounds. When only one line has been touched, this can save a good * deal of CPU time. Results are stored in globals ll_first and ll_last; */static_find_bounds(){ register struct line **std_body = SP->std_body; register struct line **cur_body = SP->cur_body; register struct line *dln; register int first = 1, last = lines; for ( ; first <= last ; first++) { dln = std_body[first]; if (dln && dln != cur_body[first]) break; } for ( ; last > first ; last--) { dln = std_body[last]; if (dln && dln != cur_body[last]) break; } ll_first = first; ll_last = last;#ifdef DEBUG if (outf) fprintf(outf, "find_bounds finds first %d last %d\n", first, last);#endif}/* * If there is typeahead waiting, don't refresh now. */static_ta_check(){ if (SP->check_fd >= 0) InputPending = _chk_input(); else InputPending = 0; if (InputPending) {#ifdef DEBUG if (outf) fprintf(outf, "InputPending %d, aborted ll_refresh at start\n", InputPending);#endif return 1; }#ifdef NONSTANDARD input_wait();#endif /* NONSTANDARD */ return 0;}static_trim_trailing_blanks(){ register chtype *p; register int i, n; register struct line *dln, *pln; register int r_last = ll_last; register struct line **std_body = SP->std_body; register struct line **cur_body = SP->cur_body; /* Get rid of trailing blanks on all lines */ for (n = ll_first; n <= r_last; n++) { dln = std_body[n]; pln = cur_body[n]; if (dln && dln != pln) { if (i = dln->length) { p = dln->body + i; while (*--p == ' ' && --i > 0) ; dln->length = i; } } if (pln) { register chtype *p; if (i = pln->length) { p = pln->body + i; while (*--p == ' ' && --i > 0) ; pln->length = i; } } }}/* * Check if we can use clr_eos. If so, set ll_clear to line * to do clr_eos from and ll_last 1 less than that. */_check_clreos(){ register int r_bot, r_last, r_first; register struct line **std_body = SP->std_body; register int i; ll_clear = 0; if ((std_body[ll_last] && std_body[ll_last]->length != 0) || !clr_eos) return; /* check if everything below ll_last is blank */ for (r_bot = lines, r_last = ll_last + 1; r_last <= r_bot; r_last++) if (std_body[r_last] && std_body[r_last]->length != 0) return; /* check how much of ll_first..ll_last is blank */ r_last = ll_last - 1; /* checked ll_last above */ r_first = ll_first; for ( ; r_last >= r_first; r_last--) if (std_body[r_last] && std_body[r_last]->length != 0) break; /* save info for later and clear out cur_body */ ll_clear = r_last + 1; for (i = ll_last; i > r_last; i--) { if (SP->cur_body[i] != SP->std_body[i]) _line_free (SP->cur_body[i]); SP->cur_body[i] = SP->std_body[i]; } ll_last = r_last;}/* * Make sure all the hash functions are the same. */static_fix_hash(){ register int n; register int r_last = ll_last; for (n = ll_first; n <= r_last; n++) { if (SP->cur_body[n] == 0) SP->cur_body[n] = _line_alloc(); if (SP->std_body[n] == 0) SP->std_body[n] = SP->cur_body[n]; else _comphash (SP->std_body[n]); _comphash (SP->cur_body[n]); }}/* * Count number of matches if we scroll 1 line and if we * don't scroll at all. This is primarily useful for the * case where we scroll the whole screen. Scrolling a portion * of the screen will be handled by the ins/del line routines, * although a special case here might buy some CPU speed. */static_chk_scroll(){ register int i, j, n; if (ll_first > 1 || ll_last < lines) return; /* Not full screen change, no scroll */ for (i=1,n=0,j=0; i<lines; i++) { if (SP->cur_body[i+1]->hash == SP->std_body[i]->hash) n++; if (SP->cur_body[i]->hash == SP->std_body[i]->hash) j++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -