static int _mvvert(int cy, int ny, int doit) { char *ve; int dy, st_1, st_n, cv; if (cy == ny) goto out; /* cost of stepwise movement */ if (cy < ny) { dy = ny-cy; st_1 = _COST(Cursor_down) * dy; st_n = _COST(Parm_down_cursor); } else { dy = cy-ny; st_1 = _COST(Cursor_up) * dy; st_n = _COST(Parm_up_cursor); } /* cost of using vertical move */ cv = _COST(Row_address); /* if calculating cost only */ if (!doit) return ((cv < st_1 && cv < st_n) ? cv : (st_n < st_1) ? st_n : st_1); /* do it */ if (cv < st_1 && cv < st_n) _PUTS(tparm_p1(row_address, ny), 1); else if (st_n < st_1) { if (cy < ny) _PUTS(tparm_p1(parm_down_cursor, dy), 1); else _PUTS(tparm_p1(parm_up_cursor, dy), 1); } else { if (cy < ny) ve = cursor_down; else ve = cursor_up; for (; dy > 0; --dy) _PUTS(ve, 1); } out: return (0); }
void _init_costs(void) { short *costptr = &(SP->term_costs.icfixed); char **str_array = (char **) cur_strs; int i = 0; char save_xflag = xon_xoff; xon_xoff = 0; /* * This next block of code is actually correct in that it takes into * account many things that wrefresh has to keep figuring in the function * _useidch. Wrefresh MUST be changed (in the words of Tony Hansen) !!! * * Wrefresh has been changed (in my words -Phong Vo) !!!! */ *costptr++ = ((enter_insert_mode) && (exit_insert_mode)) ? _cost_fn(enter_insert_mode, 0) + _cost_fn(exit_insert_mode, 0) : 0; *costptr++ = ((enter_delete_mode) && (exit_delete_mode)) ? _cost_fn(enter_delete_mode, 0) + _cost_fn(exit_delete_mode, 0) : 0; while (i < FIRST_LOOP) *costptr++ = _cost_fn(str_array[offsets[i++]], 1); while (i < SECOND_LOOP) *costptr++ = _cost_fn(tparm_p1(str_array[offsets[i++]], 10), 1); *costptr++ = _cost_fn(tparm_p2(cursor_address, 8, 10), 1); *costptr++ = _cost_fn(tparm_p1(row_address, 8), 1); xon_xoff = save_xflag; #ifdef DEBUG if (outf) { fprintf(outf, "icfixed %d=%d+%d\n", _COST(icfixed), _cost_fn(enter_insert_mode, 0), _cost_fn(exit_insert_mode, 0)); fprintf(outf, "from ich1 %x '%s' %d\n", insert_character, insert_character, _cost_fn(insert_character, 1)); fprintf(outf, "ip %x '%s' %d\n", insert_padding, insert_padding, _cost_fn(insert_padding, 1)); fprintf(outf, "dcfixed %d\n", _COST(dcfixed)); } #endif /* DEBUG */ /*FALLTHROUGH*/ }
static void _useceod(int topy, int boty) { short *begns, *begch; /* skip lines already blanked */ begch = _virtscr->_firstch + topy; begns = _BEGNS + topy; for (; topy < boty; ++topy, ++begns, ++begch) if (*begns < scrco || *begch == _REDRAW) break; else *begch = _INFINITY; /* nothing to do */ if (topy + 1 >= boty) return; /* see if bottom is clear */ for (begns = _BEGNS + boty; boty < scrli; ++boty, ++begns) if (*begns < scrco) return; /* use clear-screen if appropriate */ if (topy == 0) { /* SS: colors */ if (back_color_erase) _turn_off_background(); _PUTS(clear_screen, scrli); cy = 0; cx = 0; (void) werase(curscr); } else /* use clear-to-end-of-display or delete lines */ if (clr_eos || (parm_delete_line && !memory_below)) { (void) mvcur(cy, cx, topy, 0); /* LINTED */ cy = (short) topy; cx = 0; /* SS: colors */ if (back_color_erase) _turn_off_background(); _PUTS(clr_eos ? clr_eos : tparm_p1(parm_delete_line, scrli - topy), scrli - topy); /* update curscr */ /* LINTED */ curscr->_cury = (short) topy; curscr->_curx = 0; (void) wclrtobot(curscr); } else /* no hardware support */ return; /* correct the update structure */ (void) wtouchln(_virtscr, topy, scrli, FALSE); }
static int _mvleft(int cx, int nx, int doit) { int tx, nt, x, stcost; if (!cursor_left && !parm_left_cursor) return (LARGECOST); if (cursor_left) { /* stepwise cost */ tx = cx; nt = 0; if (back_tab) { /* the TAB position >= nx */ x = (nx % TABSIZE) ? (nx / TABSIZE + 1) * TABSIZE : nx; /* # of tabs used and position after using them */ if (x < cx) { nt = (cx / TABSIZE - x / TABSIZE) + ((cx % TABSIZE) ? 1 : 0); tx = x; } } stcost = nt * _COST(Back_tab) + (tx-nx) * _COST(Cursor_left); } else stcost = LARGECOST; /* get cost only */ if (!doit) return ((_COST(Parm_left_cursor) < stcost) ? _COST(Parm_left_cursor) : stcost); /* doit */ if (_COST(Parm_left_cursor) < stcost) _PUTS(tparm_p1(parm_left_cursor, cx - nx), 1); else { for (; nt > 0; --nt) _PUTS(back_tab, 1); for (; tx > nx; --tx) _PUTS(cursor_left, 1); } return (0); }
static int _mvhor(int cx, int nx, int doit) { int st, ch, hl; if (cx == nx) goto out; /* cost using horizontal move */ ch = _COST(Row_address); /* cost doing stepwise */ st = cx < nx ? _mvright(cx, nx, FALSE) : _mvleft(cx, nx, FALSE); /* cost homeleft first */ hl = (_COST(Carriage_return) < LARGECOST) ? _COST(Carriage_return) + _mvright(0, nx, FALSE) : LARGECOST; if (!doit) return ((ch < st && ch < hl) ? ch : (hl < st ? hl : st)); if (ch < st && ch < hl) _PUTS(tparm_p1(column_address, nx), 1); else if (hl < st) { _PUTS(carriage_return, 1); (void) _mvright(0, nx, TRUE); } else { if (cx < nx) (void) _mvright(cx, nx, TRUE); else (void) _mvleft(cx, nx, TRUE); } out: return (0); }
static int _useidch(chtype *wcp, chtype *scp, int length, int maxi, int *id) { int x1, x2, blnk, idch, cost, cost_ich1, match; chtype wc; /* try deletion */ if (SP->dchok && _CHAR(*wcp) != ' ') { if ((match = _prefix(wcp, scp, length, length / 2, &idch)) > 0) cost = _COST(dcfixed) + (parm_dch ? _COST(Parm_dch) : _COST(Delete_character) * idch); else cost = _INFINITY; if (match >= cost) { /* SS: colors */ if (back_color_erase) _turn_off_background(); if (SP->dmode) { if (SP->sid_equal) { if (!(SP->phys_irm)) _ONINSERT(); } else { if (SP->phys_irm) _OFFINSERT(); _PUTS(enter_delete_mode, 1); } } if (parm_dch) _PUTS(tparm_p1(parm_dch, idch), 1); else for (x1 = 0; x1 < idch; ++x1) _PUTS(delete_character, 1); if (SP->dmode) { if (SP->eid_equal) SP->phys_irm = FALSE; _PUTS(exit_delete_mode, 1); } /* update screen image */ for (x1 = 0, x2 = idch; x2 < length; ++x1, ++x2) scp[x1] = scp[x2]; for (; x1 < length; ++x1) scp[x1] = ' '; *id = -idch; return (match); } } /* no insertion wanted or possible */ if (!(SP->ichok) || _CHAR(*scp) == ' ') return (0); /* see if insertion is worth it */ maxi = (idch = length / 2) < maxi ? idch : maxi; if ((match = _prefix(scp, wcp, length, maxi, &idch)) <= 0) return (0); /* see if inserting blanks only */ for (blnk = 0; blnk < idch; ++blnk) if (wcp[blnk] != ' ') { blnk = 0; break; } /* see if doing insertion is worth it */ cost_ich1 = idch * _COST(Insert_character); if (SP->imode) { cost = SP->phys_irm ? 0 : _COST(icfixed); if (blnk > _COST(Parm_ich) && _COST(Parm_ich) < cost_ich1) cost += _COST(Parm_ich); else if (insert_character) cost += cost_ich1; } else { if (parm_ich && _COST(Parm_ich) < cost_ich1) cost = _COST(Parm_ich); else cost = cost_ich1; } if ((cost - blnk) > match) return (0); /* perform the insertions */ /* SS: colors */ if (back_color_erase) _turn_off_background(); if (SP->imode) { if (!SP->phys_irm) _ONINSERT(); if (blnk > _COST(Parm_ich) && _COST(Parm_ich) < cost_ich1) _PUTS(tparm_p1(parm_ich, idch), 1); else if (insert_character) goto do_insert_char; else /* so that we'll do real char insertions */ blnk = 0; } else { if (parm_ich && _COST(Parm_ich) < cost_ich1) _PUTS(tparm_p1(parm_ich, idch), 1); else { do_insert_char: for (x1 = 0; x1 < idch; ++x1) _PUTS(insert_character, 1); } } /* inserting desired characters */ if (!blnk) for (x1 = 0; x1 < idch; ++x1) { wc = wcp[x1]; if (_ATTR(wc) != curscr->_attrs) _VIDS(_ATTR(wc), curscr->_attrs); (void) _outwch(_CHAR(wc) == '~' && tilde_glitch ? '`' : wc); ++cx; } /* update the screen image */ for (x1 = length - 1, x2 = length - idch - 1; x2 >= 0; --x1, --x2) scp[x1] = scp[x2]; (void) memcpy((char *) scp, (char *) wcp, idch * sizeof (chtype)); *id = idch; return (match + idch); }
static void _rmargin(int wx) { int x, w, ix; chtype sc; chtype *wcp = _virtscr->_y[cy]; /* screen may scroll */ if (cy == scrli - 1) { /* can't do anything */ if (!SP->ichok) return; /* the width of the new character */ w = _curs_scrwidth[TYPE(RBYTE(wcp[wx]))]; /* the place to put it without causing scrolling */ for (x = wx - 1; x > 0; --x) if (!ISCBIT(wcp[x])) break; sc = curscr->_y[cy][x]; (void) mvcur(cy, cx, cy, x); if (_ATTR(wcp[wx]) != curscr->_attrs) _VIDS(_ATTR(wcp[wx]), curscr->_attrs); (void) _outwch(tilde_glitch && _CHAR(wcp[wx]) == '~' ? '`' : wcp[wx]); for (ix = wx + 1; ix < scrco; ++ix) { (void) _outwch(wcp[ix]); } /* insert sc back in and push wcp[wx] right */ (void) mvcur(cy, x+w, cy, x); /* SS: colors */ if (back_color_erase) _turn_off_background(); if (SP->imode && !SP->phys_irm) _ONINSERT(); /* width of the old character that was overwritten */ w = _curs_scrwidth[TYPE(RBYTE(curscr->_y[cy][x]))]; if (insert_character) for (ix = 0; ix < w; ++ix) _PUTS(insert_character, 1); else if (parm_ich && !SP->imode) _PUTS(tparm_p1(parm_ich, w), 1); if (_ATTR(sc) != curscr->_attrs) _VIDS(_ATTR(sc), curscr->_attrs); for (ix = x; w > 0; --w, ++ix) (void) _outwch(curscr->_y[cy][ix]); /* make sure the video attrs are ok */ if (marks && (_ATTR(sc) || _ATTR(wcp[wx]))) _VIDS(_ATTR(wcp[wx]), ~_ATTR(sc)); /* update screen image */ /* LINTED */ cx = (short) wx; curscr->_y[cy][wx] = wcp[wx]; for (x = wx + 1; x < scrco; ++x) { (void) _outwch(wcp[x]); curscr->_y[cy][x] = wcp[x]; } return; } /* put char out and update screen image */ (void) _outwch(tilde_glitch && _CHAR(wcp[wx]) == '~' ? '`' : wcp[wx]); curscr->_y[cy][wx] = wcp[wx]; for (x = wx + 1; x < scrco; ++x) { (void) _outwch(wcp[x]); curscr->_y[cy][x] = wcp[x]; } /* make sure that wrap-around happens */ if (!auto_right_margin || eat_newline_glitch) { (void) _outch('\r'); (void) _outch('\n'); } cx = 0; ++cy; }
static int _mvright(int cx, int nx, int doit) { chtype *scp; char *mks; int nt, tx, x, stcost, iscont; if (!cursor_right && !parm_right_cursor) return (LARGECOST); scp = curscr->_y[Newy]; mks = magic_cookie_glitch >= 0 ? SP->_mks[Newy] : NULL; if (cursor_right) { /* number of tabs used in stepwise movement */ nt = tab ? (nx / TABSIZE - cx / TABSIZE) : 0; tx = (nt > 0) ? (cx / TABSIZE + nt) * TABSIZE : cx; /* calculate stepwise cost */ stcost = nt * _COST(Tab); iscont = 0; for (x = tx; x < nx; ++x) { if (iscont == 0 && !ISCBIT(scp[x])) iscont = 1; if ((!ceol_standout_glitch && !mks && _ATTR(scp[x]) == curscr->_attrs) || ceol_standout_glitch || (mks && !_ISMARK2(x))) { if (!ISMBIT(scp[x])) stcost += 1; else if (iscont && !(nx - x == 1 && nx < curscr->_maxx && ISCBIT(scp[nx]))) stcost += 1; else stcost += _COST(Cursor_right); } else stcost += _COST(Cursor_right); } } else stcost = LARGECOST; if (!doit) return ((_COST(Parm_right_cursor) < stcost) ? _COST(Parm_right_cursor) : stcost); /* actually move */ if (_COST(Parm_right_cursor) < stcost) _PUTS(tparm_p1(parm_right_cursor, nx-cx), 1); else { if (SP->phys_irm) _OFFINSERT(); for (; nt > 0; --nt) _PUTS(tab, 1); iscont = 0; for (x = tx; x < nx; ++x) { if (iscont == 0 && !ISCBIT(scp[x])) iscont = 1; if ((!ceol_standout_glitch && !mks && _ATTR(scp[x]) == curscr->_attrs) || ceol_standout_glitch || (mks && !_ISMARK2(x))) { if (!ISMBIT(scp[x])) (void) _outwch(_CHAR(scp[x])); else if (iscont && !(nx - x == 1 && nx < curscr->_maxx && ISCBIT(scp[nx]))) (void) _outwch(_CHAR(scp[x])); else _PUTS(cursor_right, 1); } else _PUTS(cursor_right, 1); } } return (0); }
void _change_color(short newcolor, int (*outc)(char)) { #ifndef PC6300PLUS { _Color_pair *ptp = cur_term->_pairs_tbl; /* pairs table pointer */ _Color_pair *cur_pair = &cur_term->_cur_pair; /* MORE: we may have to change some stuff, depending on whether */ /* HP terminals will be changing the background, or not */ if (newcolor == 0) { if (orig_pair) (void) tputs(tparm_p0(orig_pair), 1, outc); if (set_a_background || set_a_foreground || set_background || set_foreground) { cur_pair->background = -1; cur_pair->foreground = -1; } return; } /* if we are on HP type terminal, just send an escape sequence */ /* to use desired color pair (we could have done some optimization: */ /* check if both the foreground and background of newcolor match */ /* the ones of cur_term->_cur_pair. but that will happen only when */ /* two color pairs are defined exacly the same, and probably not */ /* worth the effort). */ if (set_color_pair) (void) tputs(tparm_p1(set_color_pair, newcolor), 1, outc); /* on Tek model we can do some optimization. */ else { if (ptp[newcolor].background != cur_pair->background) { if (set_a_background) (void) tputs(tparm_p1(set_a_background, ptp[newcolor].background), 1, outc); else if (set_background) (void) tputs(tparm_p1(set_background, Oldcolors[ptp[newcolor].background]), 1, outc); cur_pair->background = ptp[newcolor].background; } if (ptp[newcolor].foreground != cur_pair->foreground) { if (set_a_foreground) (void) tputs(tparm_p1(set_a_foreground, ptp[newcolor].foreground), 1, outc); else if (set_foreground) (void) tputs(tparm_p1(set_foreground, Oldcolors[ptp[newcolor].foreground]), 1, outc); cur_pair->foreground = ptp[newcolor].foreground; } } } #else { /* the following code is for PC6300 PLUS: it uses BOLD terminfo */ /* entry for turning on colors, and SGR0 for turning them off. */ /* Every time a new color-pair is used, we are forced to do an */ /* ioctl read, and the send 'enter_bold_mode' escape sequence. */ /* This could be improved by using */ /* DIM, UNDERLINE, and REVERSE in addition to BOLD */ struct console con; _Color_pair *ptp = cur_term->_pairs_tbl; /* pairs table pointer */ back = ptp[newcolor].background; fore = ptp[newcolor].foreground; (void) fflush(SP->term_file); ioctl(cur_term->Filedes, CONIOGETDATA, &con); #define BOLD 4 con.l[con.page].colors[BOLD] = ((back + back + (fore > 5)) * 8 + fore) & 0177; ioctl(cur_term->Filedes, CONIOSETDATA, &con); (void) tputs(enter_bold_mode, 1, outc); } #endif }