📄 trm.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[] = "@(#)trm.c 1.1 92/07/30 SMI"; /* from S5R3 1.4 */#endif#include "curses.ext"extern _outch();char *tparm();/* * Set the virtual insert/replacement mode to new. */_insmode (new)int new;{#ifdef DEBUG if(outf) fprintf(outf, "_insmode(%d).\n", new);#endif SP->virt_irm = new;}/* * Output the string to get us in the right highlight mode, * no matter what mode we are currently in. */_forcehl(){#ifdef DEBUG if(outf) fprintf(outf, "_forcehl().\n");#endif SP->phys_gr = -1; _sethl();}_clearhl (){#ifdef DEBUG if(outf) fprintf(outf, "_clearhl().\n");#endif if (SP->phys_gr) { register oldes = SP->virt_gr; SP->virt_gr = 0; _sethl (); SP->virt_gr = oldes; }}_inslines (n){ register int i;#ifdef DEBUG if(outf) fprintf(outf, "_inslines(%d).\n", n);#endif if (!move_standout_mode && SP->phys_gr) _clearhl(); if (SP->phys_y + n >= lines && clr_eos) { /* * Really quick -- clear to end of screen. */ tputs(clr_eos, lines-SP->phys_y, _outch); return; } /* * We are about to shove something off the bottom of the screen. * Terminals with extra memory keep this around, and it might * show up again to haunt us later if we do a delete line or * scroll into it, or when we exit. So we clobber it now. We * might get better performance by somehow remembering that this * stuff is down there and worrying about it if/when we have to. * In particular, having to do this extra pair of SP->curptr motions * is a lose. */ if (memory_below && SP->phys_bot_mgn == lines-1) { int save = SP->phys_y, savetm = SP->phys_top_mgn, savebm=SP->phys_bot_mgn; if (save_cursor && restore_cursor) tputs(save_cursor, 1, _outch); if (clr_eos) { _pos(lines-n, 0); tputs(clr_eos, n, _outch); } else { for (i=0; i<n; i++) { _pos(lines-n+i, 0); _clreol(); } } if (save_cursor && restore_cursor) tputs(restore_cursor, 1, _outch); else _pos(save, 0); /* _pos might clobber scrolling region, put it back */ if (savetm!=SP->phys_top_mgn || savebm!=SP->phys_bot_mgn) { _window(savetm, savebm, 0, columns-1); _setwind(); } } /* Do the physical line deletion */ if ((scroll_reverse || (parm_rindex && !memory_above)) && SP->phys_y == SP->des_top_mgn /* &&costSR<costAL */) { /* * Use reverse scroll mode of the terminal, at * the top of the window. Reverse linefeed works * too, since we only use it from top line of window. */ _setwind(); if (parm_rindex && (n > 3 || !scroll_reverse) && !memory_above) { _pos(SP->phys_y, 0); tputs(tparm(parm_rindex, n), n, _outch); SP->ml_above -= n; if (SP->ml_above < 0) SP->ml_above = 0; } else for (i = n; i > 0; i--) { _pos(SP->phys_y, 0); tputs(scroll_reverse, 1, _outch); if (SP->ml_above > 0) SP->ml_above--; /* * If we are at the top of the screen, and the * terminal retains display above, then we * should try to clear to end of line. * Have to use CE since we don't remember what * is actually on the line. */ if (clr_eol && memory_above) tputs(clr_eol, 1, _outch); } } else if (parm_insert_line && (n>1 || !insert_line)) { tputs(tparm(parm_insert_line, n), lines-SP->phys_y, _outch); } else if (change_scroll_region && !(insert_line) && save_cursor && restore_cursor && (scroll_reverse || parm_rindex)) { /* vt100 change scrolling region to fake AL */ tputs(save_cursor, 1, _outch); tputs( tparm(change_scroll_region, SP->phys_y, SP->des_bot_mgn), 1, _outch); /* change_scroll_region homes stupid cursor */ tputs(restore_cursor, 1, _outch); if (parm_rindex && (n > 3 || !scroll_reverse)) tputs(tparm(parm_rindex, n), n, _outch); else for (i=n; i>0; i--) /* should do @'s */ tputs(scroll_reverse, 1, _outch); /* restore scrolling region */ tputs(tparm(change_scroll_region, SP->des_top_mgn, SP->des_bot_mgn), 1, _outch); tputs(restore_cursor, 1, _outch);/* Once again put it back */ SP->phys_top_mgn = SP->des_top_mgn; SP->phys_bot_mgn = SP->des_bot_mgn; } else { tputs(insert_line, lines - SP->phys_y, _outch); for (i = n - 1; i > 0; i--) { tputs(insert_line, lines - SP->phys_y, _outch); } }}_dellines (n){ register int i;#ifdef DEBUG if(outf) fprintf(outf, "_dellines(%d).\n", n);#endif if (lines - SP->phys_y <= n && (clr_eol && n == 1 || clr_eos)) { tputs(clr_eos, n, _outch); } else if ((scroll_forward || parm_index) && SP->phys_y == SP->des_top_mgn /* &&costSF<costDL */) { /* * Use forward scroll mode of the terminal, at * the bottom of the window. Linefeed works * too, since we only use it from the bottom line. */ _setwind(); if (parm_index && (n > 3 || !scroll_forward)) { _pos(SP->des_bot_mgn, 0); tputs(tparm(parm_index, n), n, _outch); } else for (i = n; i > 0; i--) { _pos(SP->des_bot_mgn, 0); tputs(scroll_forward, 1, _outch); } SP->ml_above += n; _pos(SP->des_top_mgn, 0); if (SP->ml_above + lines > lines_of_memory) SP->ml_above = lines_of_memory - lines; } else if (parm_delete_line && (n>1 || !(delete_line))) { tputs(tparm(parm_delete_line, n), lines-SP->phys_y, _outch); } else if (change_scroll_region && !(delete_line) && save_cursor && restore_cursor && (scroll_forward || parm_index)) { /* vt100: fake delete_line by changing scrolling region */ /* Save since change_scroll_region homes stupid cursor */ tputs(save_cursor, 1, _outch); tputs(tparm(change_scroll_region, SP->phys_y, SP->des_bot_mgn), 1, _outch); /* go to bottom left corner.. */ tputs(tparm(cursor_address, SP->des_bot_mgn, 0), 1, _outch); if (parm_index && (n > 3 || !scroll_forward)) tputs(tparm(parm_index, n), n, _outch); else for (i=0; i<n; i++) /* .. and scroll n times */ tputs(scroll_forward, 1, _outch); /* restore scrolling region */ tputs(tparm(change_scroll_region, SP->des_top_mgn, SP->des_bot_mgn), 1, _outch); tputs(restore_cursor, 1, _outch); /* put SP->curptr back */ SP->phys_top_mgn = SP->des_top_mgn; SP->phys_bot_mgn = SP->des_bot_mgn; } else { for (i = 0; i < n; i++) tputs(delete_line, lines-SP->phys_y, _outch); }}/* * Scroll the terminal forward n lines, bringing up blank lines from bottom. * This only affects the current scrolling region. */_scrollf(n)int n;{ register int i; if (scroll_forward || parm_index) { _setwind(); _pos(SP->des_bot_mgn, 0); if (parm_index && (n > 3 || !scroll_forward)) tputs(tparm(parm_index, n), n, _outch); else for (i=0; i<n; i++) tputs(scroll_forward, 1, _outch); SP->ml_above += n; if (SP->ml_above + lines > lines_of_memory) SP->ml_above = lines_of_memory - lines; } else { /* Braindamaged terminal can't do it, try delete line. */ _pos(0, 0); _dellines(n); if (memory_below) { _pos(lines-1, 0); /* go back to the bottom */ _inslines(n); /* to add blank lines */ } }}/* * writechars: write the characters from *start through *end out to the * terminal. Keep track of the cursor position. Do anything terminal * specific that is necessary to get the job done right or more efficiently. */_writechars (start, end, leftch)register char *start, *end;chtype leftch;{ register int c; register char *p; register int clrhlflag = 0; int savetm, savebm = SP->phys_bot_mgn; char *beginning = start; extern int didntdobotright;#ifdef DEBUG if(outf) { fprintf(outf, "_writechars(%d:'", end-start+1); fwrite(start, sizeof (char), end-start+1, outf); fprintf(outf, "', leftch=0%o).\n", leftch); }#endif _setmode (); _sethl(); while (start <= end) {#ifdef FULLDEBUG if(outf) fprintf(outf, "wc loop: repeat_char '%s', SP->phys_irm %d, *start '%c'\n", repeat_char, SP->phys_irm, *start);#endif if (repeat_char && SP->phys_irm != 1 && ((p=start+1),*start==*p++) && (*start==*p++) && (*start==*p++) && (*start==*p++) && p<=end) { /* We have a run of at least 5 characters */ c = 5; while (p <= end && *start == *p) p++, c++; SP->phys_x += c; /* Do not assume anything about how repeat and auto * margins interact. The concept botches it. */ if (auto_right_margin) { int overshot = (SP->phys_x+1) - columns; if (overshot > 0) { c -= overshot; p -= overshot; SP->phys_x -= overshot; } }#ifdef DEBUG if(outf) fprintf(outf, "using repeat, count %d, char '%c'\n", c, *start);#endif if (*start == '~' && tilde_glitch) *start = '`'; tputs(tparm(repeat_char, *start, c), c, _outch); start = p; continue; } c = *start++; if (c == '~' && tilde_glitch) c = '`';#ifdef DEBUG if (outf) fprintf(outf, "c is '%c', phys_x %d, phys_y %d\n", c, SP->phys_x, SP->phys_y);#endif if(SP->phys_irm == 1 && insert_character) tputs(insert_character, columns-SP->phys_x, _outch); /* * If transparent_underline && !erase_overstrike, * should probably do clr_eol. No such terminal yet. * We do clr_eol at the end of the line to avoid * wrapping. */ if (transparent_underline && erase_overstrike && c == '_' && SP->phys_irm != 1) if (SP->phys_x >= columns - 1) tputs(clr_eol, 1, _outch); else { _outch (' '); tputs(cursor_left, 1, _outch); } if (++SP->phys_x >= columns) { /* * The bottom right corner of a scrolling * region is just as bad as the bottom * right corner of the screen. We can at * least control the scrolling region. */ if (SP->phys_y>=SP->phys_bot_mgn) { savetm = SP->phys_top_mgn; _window(0, lines-1, 0, columns-1); _setwind(); } if (auto_right_margin) { if (SP->phys_gr && !move_standout_mode) clrhlflag = 1; /* Have to on c100 anyway..*/ if (SP->phys_y >= lines-1) { /*&& !eat_newline_glitch*/ /* * We attempted to put something * in the last position of the * last line. Since this will * cause a scroll (we only get * here if the terminal has * auto_right_margin) we refuse * to put it out. * * Well, on second thought, if we * back up a character, we can * type the character, back up * again, and re-INSERT the * character that used to be * there before. * * This algorithm is from Tony Hansen * and Mitch Baker. */#ifdef DEBUG if (outf) fprintf(outf, "Avoiding lower right corner\n");#endif /* * For now, only do this if the * terminal has cursor_left. If we * want to be complete, we should
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -