1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1988 AT&T */ 28*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate /* 31*7c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 32*7c478bd9Sstevel@tonic-gate * The Regents of the University of California 33*7c478bd9Sstevel@tonic-gate * All Rights Reserved 34*7c478bd9Sstevel@tonic-gate * 35*7c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 36*7c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 37*7c478bd9Sstevel@tonic-gate * contributors. 38*7c478bd9Sstevel@tonic-gate */ 39*7c478bd9Sstevel@tonic-gate 40*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gate /*LINTLIBRARY*/ 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 45*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 46*7c478bd9Sstevel@tonic-gate #include <string.h> 47*7c478bd9Sstevel@tonic-gate #include "curses_inc.h" 48*7c478bd9Sstevel@tonic-gate 49*7c478bd9Sstevel@tonic-gate /* 50*7c478bd9Sstevel@tonic-gate * Make the screen look like "win" over the area covered by win. 51*7c478bd9Sstevel@tonic-gate * This routine may use insert/delete char/line and scrolling-region. 52*7c478bd9Sstevel@tonic-gate * win : the window being updated 53*7c478bd9Sstevel@tonic-gate */ 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate extern int outchcount; 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate static void _updateln(int), _turn_off_background(void), 58*7c478bd9Sstevel@tonic-gate _setmark1(int, int, chtype *), 59*7c478bd9Sstevel@tonic-gate _setmark2(int, int, chtype *), _rmargin(int), 60*7c478bd9Sstevel@tonic-gate _useceod(int, int); 61*7c478bd9Sstevel@tonic-gate static int _useidch(chtype *, chtype *, int, int, int *), 62*7c478bd9Sstevel@tonic-gate _prefix(chtype *, chtype *, int, int, int *), 63*7c478bd9Sstevel@tonic-gate _getceod(int, int); 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate static short cy, cx, /* current cursor coord */ 66*7c478bd9Sstevel@tonic-gate scrli, /* actual screen lines */ 67*7c478bd9Sstevel@tonic-gate scrco; /* actual screen columns */ 68*7c478bd9Sstevel@tonic-gate static char **marks; /* the mark table for cookie terminals */ 69*7c478bd9Sstevel@tonic-gate static char **color_marks; /* color mark table for cookie terminals */ 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate #define _ISMARK1(y, x) (marks[y][x / BITSPERBYTE] & (1 << (x % BITSPERBYTE))) 72*7c478bd9Sstevel@tonic-gate #define _ISMARK2(y, x) (color_marks ? (color_marks[y][x / BITSPERBYTE] & \ 73*7c478bd9Sstevel@tonic-gate (1 << (x % BITSPERBYTE))) : FALSE) 74*7c478bd9Sstevel@tonic-gate 75*7c478bd9Sstevel@tonic-gate #define _VIDEO(c) ((c) & A_ATTRIBUTES & ~A_COLOR) 76*7c478bd9Sstevel@tonic-gate #define _COLOR(c) ((c) & A_COLOR) 77*7c478bd9Sstevel@tonic-gate 78*7c478bd9Sstevel@tonic-gate #ifdef _VR2_COMPAT_CODE 79*7c478bd9Sstevel@tonic-gate extern char _endwin; 80*7c478bd9Sstevel@tonic-gate #endif /* _VR2_COMPAT_CODE */ 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate int 83*7c478bd9Sstevel@tonic-gate wrefresh(WINDOW *win) 84*7c478bd9Sstevel@tonic-gate { 85*7c478bd9Sstevel@tonic-gate 86*7c478bd9Sstevel@tonic-gate short *bnsch, *ensch; 87*7c478bd9Sstevel@tonic-gate SLK_MAP *slk; 88*7c478bd9Sstevel@tonic-gate int wx, wy, nc, boty, clby, idby, *hs, curwin; 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate curwin = (win == curscr); 91*7c478bd9Sstevel@tonic-gate 92*7c478bd9Sstevel@tonic-gate /* don't allow curscr refresh if the screen was just created */ 93*7c478bd9Sstevel@tonic-gate 94*7c478bd9Sstevel@tonic-gate if (curwin && curscr->_sync) 95*7c478bd9Sstevel@tonic-gate return (OK); 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate /* go thru _stdbody */ 98*7c478bd9Sstevel@tonic-gate if (!curwin && (win != _virtscr)) 99*7c478bd9Sstevel@tonic-gate (void) wnoutrefresh(win); 100*7c478bd9Sstevel@tonic-gate 101*7c478bd9Sstevel@tonic-gate /* if there is typeahead */ 102*7c478bd9Sstevel@tonic-gate if ((_INPUTPENDING = _chkinput()) == TRUE) { 103*7c478bd9Sstevel@tonic-gate if (curwin) 104*7c478bd9Sstevel@tonic-gate curscr->_clear = TRUE; 105*7c478bd9Sstevel@tonic-gate return (OK); 106*7c478bd9Sstevel@tonic-gate } 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate if (curwin || curscr->_clear) 109*7c478bd9Sstevel@tonic-gate _virtscr->_clear = TRUE; 110*7c478bd9Sstevel@tonic-gate 111*7c478bd9Sstevel@tonic-gate /* save curscr cursor coordinates */ 112*7c478bd9Sstevel@tonic-gate cy = curscr->_cury; 113*7c478bd9Sstevel@tonic-gate cx = curscr->_curx; 114*7c478bd9Sstevel@tonic-gate 115*7c478bd9Sstevel@tonic-gate /* to simplify code in some cases */ 116*7c478bd9Sstevel@tonic-gate marks = _MARKS; 117*7c478bd9Sstevel@tonic-gate color_marks = _COLOR_MARKS; 118*7c478bd9Sstevel@tonic-gate scrli = curscr->_maxy; 119*7c478bd9Sstevel@tonic-gate scrco = curscr->_maxx; 120*7c478bd9Sstevel@tonic-gate slk = SP->slk; 121*7c478bd9Sstevel@tonic-gate 122*7c478bd9Sstevel@tonic-gate outchcount = 0; 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate /* make sure we're in program mode */ 125*7c478bd9Sstevel@tonic-gate if (SP->fl_endwin) { 126*7c478bd9Sstevel@tonic-gate /* If endwin is equal to 2 it means we just did a newscreen. */ 127*7c478bd9Sstevel@tonic-gate if (SP->fl_endwin == TRUE) { 128*7c478bd9Sstevel@tonic-gate (void) reset_prog_mode(); 129*7c478bd9Sstevel@tonic-gate if (SP->kp_state) 130*7c478bd9Sstevel@tonic-gate (void) tputs(keypad_xmit, 1, _outch); 131*7c478bd9Sstevel@tonic-gate if (slk) 132*7c478bd9Sstevel@tonic-gate (*_do_slk_tch)(); 133*7c478bd9Sstevel@tonic-gate if (SP->fl_meta) 134*7c478bd9Sstevel@tonic-gate (void) tputs(meta_on, 1, _outch); 135*7c478bd9Sstevel@tonic-gate if (cur_term->_cursorstate != 1) 136*7c478bd9Sstevel@tonic-gate _PUTS(cur_term->cursor_seq[cur_term-> 137*7c478bd9Sstevel@tonic-gate _cursorstate], 0); 138*7c478bd9Sstevel@tonic-gate } 139*7c478bd9Sstevel@tonic-gate _PUTS(enter_ca_mode, 1); 140*7c478bd9Sstevel@tonic-gate (void) tputs(ena_acs, 1, _outch); 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gate if (exit_attribute_mode) 143*7c478bd9Sstevel@tonic-gate _PUTS(tparm_p0(exit_attribute_mode), 1); 144*7c478bd9Sstevel@tonic-gate else 145*7c478bd9Sstevel@tonic-gate /* 146*7c478bd9Sstevel@tonic-gate * If there is no exit_attribute mode, then vidupdate 147*7c478bd9Sstevel@tonic-gate * could only possibly turn off one of the below three 148*7c478bd9Sstevel@tonic-gate * so that's all we ask it turn off. 149*7c478bd9Sstevel@tonic-gate */ 150*7c478bd9Sstevel@tonic-gate vidupdate(A_NORMAL, (A_ALTCHARSET | A_STANDOUT | 151*7c478bd9Sstevel@tonic-gate A_UNDERLINE), _outch); 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate SP->fl_endwin = FALSE; 154*7c478bd9Sstevel@tonic-gate 155*7c478bd9Sstevel@tonic-gate #ifdef _VR2_COMPAT_CODE 156*7c478bd9Sstevel@tonic-gate _endwin = (char) FALSE; 157*7c478bd9Sstevel@tonic-gate #endif /* _VR2_COMPAT_CODE */ 158*7c478bd9Sstevel@tonic-gate } 159*7c478bd9Sstevel@tonic-gate 160*7c478bd9Sstevel@tonic-gate /* clear the screen if required */ 161*7c478bd9Sstevel@tonic-gate if (_virtscr->_clear) { 162*7c478bd9Sstevel@tonic-gate /* SS: colors */ 163*7c478bd9Sstevel@tonic-gate if (back_color_erase) 164*7c478bd9Sstevel@tonic-gate _turn_off_background(); 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate _PUTS(clear_screen, scrli); 167*7c478bd9Sstevel@tonic-gate cy = cx = curscr->_curx = curscr->_cury = 0; 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate /* _sync indicates that this a new screen */ 170*7c478bd9Sstevel@tonic-gate if (!curscr->_sync) 171*7c478bd9Sstevel@tonic-gate (void) werase(curscr); 172*7c478bd9Sstevel@tonic-gate else { 173*7c478bd9Sstevel@tonic-gate nc = scrco / BITSPERBYTE - (scrco % 174*7c478bd9Sstevel@tonic-gate BITSPERBYTE ? 0 : 1); 175*7c478bd9Sstevel@tonic-gate wy = scrli - 1; 176*7c478bd9Sstevel@tonic-gate bnsch = _BEGNS; ensch = _ENDNS; 177*7c478bd9Sstevel@tonic-gate hs = _CURHASH; 178*7c478bd9Sstevel@tonic-gate for (; wy >= 0; --wy) { 179*7c478bd9Sstevel@tonic-gate *bnsch++ = scrco; 180*7c478bd9Sstevel@tonic-gate *ensch++ = -1; 181*7c478bd9Sstevel@tonic-gate *hs++ = 0; 182*7c478bd9Sstevel@tonic-gate if (marks) 183*7c478bd9Sstevel@tonic-gate for (wx = nc; wx >= 0; --wx) 184*7c478bd9Sstevel@tonic-gate marks[wy][wx] = 0; 185*7c478bd9Sstevel@tonic-gate } 186*7c478bd9Sstevel@tonic-gate } 187*7c478bd9Sstevel@tonic-gate 188*7c478bd9Sstevel@tonic-gate _virtscr->_clear = curscr->_sync = curscr->_clear = FALSE; 189*7c478bd9Sstevel@tonic-gate if (slk) 190*7c478bd9Sstevel@tonic-gate (*_do_slk_tch)(); 191*7c478bd9Sstevel@tonic-gate 192*7c478bd9Sstevel@tonic-gate /* pretend _virtscr has been totally changed */ 193*7c478bd9Sstevel@tonic-gate (void) wtouchln(_virtscr, 0, scrli, -1); 194*7c478bd9Sstevel@tonic-gate _VIRTTOP = 0; 195*7c478bd9Sstevel@tonic-gate _VIRTBOT = scrli - 1; 196*7c478bd9Sstevel@tonic-gate 197*7c478bd9Sstevel@tonic-gate /* will not do clear-eod or ins/del lines */ 198*7c478bd9Sstevel@tonic-gate clby = idby = scrli; 199*7c478bd9Sstevel@tonic-gate } else 200*7c478bd9Sstevel@tonic-gate clby = idby = -1; 201*7c478bd9Sstevel@tonic-gate 202*7c478bd9Sstevel@tonic-gate /* Software soft labels; if _changed == 2, slk's are in clear mode. */ 203*7c478bd9Sstevel@tonic-gate if (slk && slk->_win && (slk->_changed == TRUE)) 204*7c478bd9Sstevel@tonic-gate (*_do_slk_noref)(); 205*7c478bd9Sstevel@tonic-gate 206*7c478bd9Sstevel@tonic-gate /* do line updating */ 207*7c478bd9Sstevel@tonic-gate _virtscr->_clear = FALSE; 208*7c478bd9Sstevel@tonic-gate wy = _VIRTTOP; 209*7c478bd9Sstevel@tonic-gate boty = _VIRTBOT + 1; 210*7c478bd9Sstevel@tonic-gate bnsch = _virtscr->_firstch + wy; 211*7c478bd9Sstevel@tonic-gate ensch = _virtscr->_lastch + wy; 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gate for (; wy < boty; ++wy, ++bnsch, ++ensch) { 214*7c478bd9Sstevel@tonic-gate /* this line is up-to-date */ 215*7c478bd9Sstevel@tonic-gate if (*bnsch >= scrco) 216*7c478bd9Sstevel@tonic-gate goto next; 217*7c478bd9Sstevel@tonic-gate 218*7c478bd9Sstevel@tonic-gate /* there is type-ahead */ 219*7c478bd9Sstevel@tonic-gate if (!curwin && (_INPUTPENDING = _chkinput()) == TRUE) { 220*7c478bd9Sstevel@tonic-gate /* LINTED */ 221*7c478bd9Sstevel@tonic-gate _VIRTTOP = (short) wy; 222*7c478bd9Sstevel@tonic-gate goto done; 223*7c478bd9Sstevel@tonic-gate } 224*7c478bd9Sstevel@tonic-gate 225*7c478bd9Sstevel@tonic-gate if (clby < 0) { 226*7c478bd9Sstevel@tonic-gate /* now we have to work, check for ceod */ 227*7c478bd9Sstevel@tonic-gate clby = _getceod(wy, boty); 228*7c478bd9Sstevel@tonic-gate 229*7c478bd9Sstevel@tonic-gate /* check for insert/delete lines */ 230*7c478bd9Sstevel@tonic-gate if (_virtscr->_use_idl) 231*7c478bd9Sstevel@tonic-gate idby = (*_setidln)(); 232*7c478bd9Sstevel@tonic-gate } 233*7c478bd9Sstevel@tonic-gate 234*7c478bd9Sstevel@tonic-gate /* try clear-to-eod */ 235*7c478bd9Sstevel@tonic-gate if (wy == clby) 236*7c478bd9Sstevel@tonic-gate _useceod(wy, boty); 237*7c478bd9Sstevel@tonic-gate 238*7c478bd9Sstevel@tonic-gate /* try ins/del lines */ 239*7c478bd9Sstevel@tonic-gate if (wy == idby) { 240*7c478bd9Sstevel@tonic-gate curscr->_cury = cy; 241*7c478bd9Sstevel@tonic-gate curscr->_curx = cx; 242*7c478bd9Sstevel@tonic-gate (*_useidln)(); 243*7c478bd9Sstevel@tonic-gate cy = curscr->_cury; 244*7c478bd9Sstevel@tonic-gate cx = curscr->_curx; 245*7c478bd9Sstevel@tonic-gate } 246*7c478bd9Sstevel@tonic-gate 247*7c478bd9Sstevel@tonic-gate if (*bnsch < scrco) 248*7c478bd9Sstevel@tonic-gate _updateln(wy); 249*7c478bd9Sstevel@tonic-gate 250*7c478bd9Sstevel@tonic-gate next: 251*7c478bd9Sstevel@tonic-gate *bnsch = _INFINITY; 252*7c478bd9Sstevel@tonic-gate *ensch = -1; 253*7c478bd9Sstevel@tonic-gate } 254*7c478bd9Sstevel@tonic-gate 255*7c478bd9Sstevel@tonic-gate /* do hardware soft labels; if _changed == 2, */ 256*7c478bd9Sstevel@tonic-gate /* slk's are in clear mode. */ 257*7c478bd9Sstevel@tonic-gate if (slk && (slk->_changed == TRUE) && !(slk->_win)) 258*7c478bd9Sstevel@tonic-gate (*_do_slk_ref)(); 259*7c478bd9Sstevel@tonic-gate 260*7c478bd9Sstevel@tonic-gate /* move cursor */ 261*7c478bd9Sstevel@tonic-gate wy = _virtscr->_cury; 262*7c478bd9Sstevel@tonic-gate wx = _virtscr->_curx; 263*7c478bd9Sstevel@tonic-gate if (wy != cy || wx != cx) { 264*7c478bd9Sstevel@tonic-gate (void) mvcur(cy, cx, wy, wx); 265*7c478bd9Sstevel@tonic-gate /* LINTED */ 266*7c478bd9Sstevel@tonic-gate cy = (short) wy; 267*7c478bd9Sstevel@tonic-gate /* LINTED */ 268*7c478bd9Sstevel@tonic-gate cx = (short) wx; 269*7c478bd9Sstevel@tonic-gate } 270*7c478bd9Sstevel@tonic-gate 271*7c478bd9Sstevel@tonic-gate /* reset the flags */ 272*7c478bd9Sstevel@tonic-gate curscr->_clear = FALSE; 273*7c478bd9Sstevel@tonic-gate _virtscr->_use_idl = FALSE; 274*7c478bd9Sstevel@tonic-gate _virtscr->_use_idc = TRUE; 275*7c478bd9Sstevel@tonic-gate _INPUTPENDING = FALSE; 276*7c478bd9Sstevel@tonic-gate 277*7c478bd9Sstevel@tonic-gate /* virtual image is now up-to-date */ 278*7c478bd9Sstevel@tonic-gate _VIRTTOP = scrli; 279*7c478bd9Sstevel@tonic-gate _VIRTBOT = -1; 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate done : 282*7c478bd9Sstevel@tonic-gate curscr->_cury = cy; 283*7c478bd9Sstevel@tonic-gate curscr->_curx = cx; 284*7c478bd9Sstevel@tonic-gate (void) fflush(SP->term_file); 285*7c478bd9Sstevel@tonic-gate return (outchcount); 286*7c478bd9Sstevel@tonic-gate } 287*7c478bd9Sstevel@tonic-gate 288*7c478bd9Sstevel@tonic-gate /* Shift appropriate portions of a line to leave space for cookies. */ 289*7c478bd9Sstevel@tonic-gate 290*7c478bd9Sstevel@tonic-gate static chtype * 291*7c478bd9Sstevel@tonic-gate _shove(int wy) 292*7c478bd9Sstevel@tonic-gate { 293*7c478bd9Sstevel@tonic-gate chtype *wcp, *cp, prev; 294*7c478bd9Sstevel@tonic-gate short curx; 295*7c478bd9Sstevel@tonic-gate int x, cury, didshift; 296*7c478bd9Sstevel@tonic-gate static chtype *line; 297*7c478bd9Sstevel@tonic-gate static int length; 298*7c478bd9Sstevel@tonic-gate 299*7c478bd9Sstevel@tonic-gate /* allocate space for shifted line */ 300*7c478bd9Sstevel@tonic-gate if (length < scrco) { 301*7c478bd9Sstevel@tonic-gate if (line) 302*7c478bd9Sstevel@tonic-gate free((char *) line); 303*7c478bd9Sstevel@tonic-gate line = (chtype *) malloc(scrco * sizeof (chtype)); 304*7c478bd9Sstevel@tonic-gate length = line ? scrco : 0; 305*7c478bd9Sstevel@tonic-gate } 306*7c478bd9Sstevel@tonic-gate 307*7c478bd9Sstevel@tonic-gate /* no space to do it */ 308*7c478bd9Sstevel@tonic-gate if (!line) 309*7c478bd9Sstevel@tonic-gate return (_virtscr->_y[wy]); 310*7c478bd9Sstevel@tonic-gate 311*7c478bd9Sstevel@tonic-gate prev = A_NORMAL; 312*7c478bd9Sstevel@tonic-gate cp = line; 313*7c478bd9Sstevel@tonic-gate wcp = _virtscr->_y[wy]; 314*7c478bd9Sstevel@tonic-gate curx = _virtscr->_curx; 315*7c478bd9Sstevel@tonic-gate cury = _virtscr->_cury; 316*7c478bd9Sstevel@tonic-gate didshift = FALSE; 317*7c478bd9Sstevel@tonic-gate 318*7c478bd9Sstevel@tonic-gate for (x = 0; x < scrco; ++x, ++wcp, ++cp) { 319*7c478bd9Sstevel@tonic-gate if (_ATTR(*wcp) != prev) { 320*7c478bd9Sstevel@tonic-gate /* use existing blank */ 321*7c478bd9Sstevel@tonic-gate if (_CHAR(*wcp) == ' ') 322*7c478bd9Sstevel@tonic-gate *cp = ' ' | _ATTR(*(wcp + 1)); 323*7c478bd9Sstevel@tonic-gate /* use previous blank */ 324*7c478bd9Sstevel@tonic-gate else 325*7c478bd9Sstevel@tonic-gate if ((x > 0) && _CHAR(*(cp - 1)) == ' ') { 326*7c478bd9Sstevel@tonic-gate *(cp - 1) = ' ' | _ATTR(*wcp); 327*7c478bd9Sstevel@tonic-gate *cp = *wcp; 328*7c478bd9Sstevel@tonic-gate } else { 329*7c478bd9Sstevel@tonic-gate if ((curx >= x) && (cury == wy)) 330*7c478bd9Sstevel@tonic-gate ++curx; 331*7c478bd9Sstevel@tonic-gate *cp = ' ' | _ATTR(*wcp); 332*7c478bd9Sstevel@tonic-gate --wcp; 333*7c478bd9Sstevel@tonic-gate didshift = TRUE; 334*7c478bd9Sstevel@tonic-gate } 335*7c478bd9Sstevel@tonic-gate prev = _ATTR(*cp); 336*7c478bd9Sstevel@tonic-gate } else 337*7c478bd9Sstevel@tonic-gate *cp = *wcp; 338*7c478bd9Sstevel@tonic-gate } 339*7c478bd9Sstevel@tonic-gate 340*7c478bd9Sstevel@tonic-gate /* make sure that the end of the line is normal */ 341*7c478bd9Sstevel@tonic-gate cp = line + scrco - 1; 342*7c478bd9Sstevel@tonic-gate if (didshift || (_ATTR(*cp) != A_NORMAL) || 343*7c478bd9Sstevel@tonic-gate ((wy == scrli - 1) && (_ATTR(*(cp - 1)) != A_NORMAL))) { 344*7c478bd9Sstevel@tonic-gate *cp = didshift ? ' ' : _CHAR(*cp); 345*7c478bd9Sstevel@tonic-gate if (wy == scrli - 1) 346*7c478bd9Sstevel@tonic-gate *(cp - 1) = didshift ? ' ' : _CHAR(*(cp - 1)); 347*7c478bd9Sstevel@tonic-gate } 348*7c478bd9Sstevel@tonic-gate 349*7c478bd9Sstevel@tonic-gate if (wy == cury) 350*7c478bd9Sstevel@tonic-gate _virtscr->_curx = curx >= scrco ? scrco - 1 : curx; 351*7c478bd9Sstevel@tonic-gate 352*7c478bd9Sstevel@tonic-gate return (line); 353*7c478bd9Sstevel@tonic-gate } 354*7c478bd9Sstevel@tonic-gate 355*7c478bd9Sstevel@tonic-gate /* 356*7c478bd9Sstevel@tonic-gate * Update a line. 357*7c478bd9Sstevel@tonic-gate * Three schemes of coloring are allowed. The first is the usual 358*7c478bd9Sstevel@tonic-gate * pen-up/pen-down model. The second is the HP26*-like model. 359*7c478bd9Sstevel@tonic-gate * In this case, colorings are specified by intervals, the left 360*7c478bd9Sstevel@tonic-gate * side of the interval has the coloring mark, the right side 361*7c478bd9Sstevel@tonic-gate * has the end-coloring mark. We assume that clear sequences will 362*7c478bd9Sstevel@tonic-gate * clear ALL marks in the affected regions. The second case is 363*7c478bd9Sstevel@tonic-gate * signified by the boolean flag ceol_standout_glitch. 364*7c478bd9Sstevel@tonic-gate * The third case is for terminals that leave visible cookies on 365*7c478bd9Sstevel@tonic-gate * the screen. This last case is at most an approximation of what 366*7c478bd9Sstevel@tonic-gate * can be done right. 367*7c478bd9Sstevel@tonic-gate */ 368*7c478bd9Sstevel@tonic-gate 369*7c478bd9Sstevel@tonic-gate static void 370*7c478bd9Sstevel@tonic-gate _updateln(int wy) 371*7c478bd9Sstevel@tonic-gate { 372*7c478bd9Sstevel@tonic-gate chtype *wcp, *scp, *wp, *sp, wc, sc; 373*7c478bd9Sstevel@tonic-gate int wx, lastx, x, mtch, idch, blnkx, idcx, video_attrx, 374*7c478bd9Sstevel@tonic-gate color_attrx, maxi, endns, begns, wx_sav, multi_col; 375*7c478bd9Sstevel@tonic-gate bool redraw, changed, didcolor, didvideo; 376*7c478bd9Sstevel@tonic-gate 377*7c478bd9Sstevel@tonic-gate redraw = (_virtscr->_firstch[wy] == _REDRAW); 378*7c478bd9Sstevel@tonic-gate endns = _ENDNS[wy]; 379*7c478bd9Sstevel@tonic-gate begns = _BEGNS[wy]; 380*7c478bd9Sstevel@tonic-gate 381*7c478bd9Sstevel@tonic-gate /* easy case */ 382*7c478bd9Sstevel@tonic-gate if (!redraw && (_virtscr->_lastch[wy] == _BLANK) && (begns >= scrco)) 383*7c478bd9Sstevel@tonic-gate return; 384*7c478bd9Sstevel@tonic-gate 385*7c478bd9Sstevel@tonic-gate /* line images */ 386*7c478bd9Sstevel@tonic-gate wcp = magic_cookie_glitch <= 0 ? _virtscr->_y[wy] : _shove(wy); 387*7c478bd9Sstevel@tonic-gate scp = curscr->_y[wy]; 388*7c478bd9Sstevel@tonic-gate 389*7c478bd9Sstevel@tonic-gate /* the interval to be updated */ 390*7c478bd9Sstevel@tonic-gate if (redraw || magic_cookie_glitch >= 0) { 391*7c478bd9Sstevel@tonic-gate wx = 0; 392*7c478bd9Sstevel@tonic-gate lastx = scrco; 393*7c478bd9Sstevel@tonic-gate } else { 394*7c478bd9Sstevel@tonic-gate wx = _virtscr->_firstch[wy]; 395*7c478bd9Sstevel@tonic-gate lastx = _virtscr->_lastch[wy] == _BLANK ? scrco : 396*7c478bd9Sstevel@tonic-gate _virtscr->_lastch[wy] + 1; 397*7c478bd9Sstevel@tonic-gate } 398*7c478bd9Sstevel@tonic-gate 399*7c478bd9Sstevel@tonic-gate /* skip equal parts */ 400*7c478bd9Sstevel@tonic-gate if (!redraw) { 401*7c478bd9Sstevel@tonic-gate /* skip the starting equal part */ 402*7c478bd9Sstevel@tonic-gate wp = wcp + wx; 403*7c478bd9Sstevel@tonic-gate sp = scp + wx; 404*7c478bd9Sstevel@tonic-gate for (; wx < lastx; ++wx) 405*7c478bd9Sstevel@tonic-gate if (*wp++ != *sp++) 406*7c478bd9Sstevel@tonic-gate break; 407*7c478bd9Sstevel@tonic-gate if (wx >= lastx) 408*7c478bd9Sstevel@tonic-gate return; 409*7c478bd9Sstevel@tonic-gate 410*7c478bd9Sstevel@tonic-gate /* start update at an entire character */ 411*7c478bd9Sstevel@tonic-gate for (sp = scp+wx, wp = wcp+wx; wp > wcp; --wp, --sp, --wx) 412*7c478bd9Sstevel@tonic-gate if (!ISCBIT(*wp) && !ISCBIT(*sp)) 413*7c478bd9Sstevel@tonic-gate break; 414*7c478bd9Sstevel@tonic-gate 415*7c478bd9Sstevel@tonic-gate /* skip the ending equal part */ 416*7c478bd9Sstevel@tonic-gate wp = wcp + lastx - 1; 417*7c478bd9Sstevel@tonic-gate sp = scp + lastx - 1; 418*7c478bd9Sstevel@tonic-gate for (; lastx > wx; --lastx) 419*7c478bd9Sstevel@tonic-gate if (*wp-- != *sp--) 420*7c478bd9Sstevel@tonic-gate break; 421*7c478bd9Sstevel@tonic-gate ++wp; 422*7c478bd9Sstevel@tonic-gate ++wp; 423*7c478bd9Sstevel@tonic-gate ++sp; 424*7c478bd9Sstevel@tonic-gate ++sp; 425*7c478bd9Sstevel@tonic-gate for (; lastx < scrco; ++wp, ++sp, ++lastx) 426*7c478bd9Sstevel@tonic-gate if (!ISCBIT(*wp) && !ISCBIT(*sp)) 427*7c478bd9Sstevel@tonic-gate break; 428*7c478bd9Sstevel@tonic-gate } 429*7c478bd9Sstevel@tonic-gate 430*7c478bd9Sstevel@tonic-gate /* place to do clear-eol */ 431*7c478bd9Sstevel@tonic-gate if (!clr_eol || endns >= lastx) 432*7c478bd9Sstevel@tonic-gate blnkx = scrco; 433*7c478bd9Sstevel@tonic-gate else 434*7c478bd9Sstevel@tonic-gate if (_virtscr->_lastch[wy] == _BLANK) 435*7c478bd9Sstevel@tonic-gate blnkx = -1; 436*7c478bd9Sstevel@tonic-gate else { 437*7c478bd9Sstevel@tonic-gate for (blnkx = lastx - 1, wp = wcp + blnkx; 438*7c478bd9Sstevel@tonic-gate blnkx >= wx; --blnkx, --wp) 439*7c478bd9Sstevel@tonic-gate if (_DARKCHAR(*wp)) 440*7c478bd9Sstevel@tonic-gate break; 441*7c478bd9Sstevel@tonic-gate for (sp = scp + blnkx + 1; blnkx < scrco - 1; 442*7c478bd9Sstevel@tonic-gate ++sp, ++blnkx) 443*7c478bd9Sstevel@tonic-gate if (!ISCBIT(*sp)) 444*7c478bd9Sstevel@tonic-gate break; 445*7c478bd9Sstevel@tonic-gate if (blnkx + _COST(Clr_eol) >= lastx) 446*7c478bd9Sstevel@tonic-gate blnkx = scrco; 447*7c478bd9Sstevel@tonic-gate } 448*7c478bd9Sstevel@tonic-gate 449*7c478bd9Sstevel@tonic-gate /* on cookie terminals, we may need to do more work */ 450*7c478bd9Sstevel@tonic-gate if (marks) { 451*7c478bd9Sstevel@tonic-gate /* video_attrx = color_attrx = scrco; */ 452*7c478bd9Sstevel@tonic-gate video_attrx = color_attrx = (lastx >= scrco) ? lastx - 1 : 453*7c478bd9Sstevel@tonic-gate lastx; 454*7c478bd9Sstevel@tonic-gate 455*7c478bd9Sstevel@tonic-gate /* find the last video attribute on the line */ 456*7c478bd9Sstevel@tonic-gate 457*7c478bd9Sstevel@tonic-gate wp = wcp + video_attrx; 458*7c478bd9Sstevel@tonic-gate for (; video_attrx >= wx; --video_attrx, --wp) 459*7c478bd9Sstevel@tonic-gate if (_VIDEO(*wp) != A_NORMAL) 460*7c478bd9Sstevel@tonic-gate break; 461*7c478bd9Sstevel@tonic-gate 462*7c478bd9Sstevel@tonic-gate /* find the last color attribute on the line */ 463*7c478bd9Sstevel@tonic-gate 464*7c478bd9Sstevel@tonic-gate if (color_marks) { 465*7c478bd9Sstevel@tonic-gate wp = wcp + color_attrx; 466*7c478bd9Sstevel@tonic-gate for (; color_attrx >= wx; --color_attrx, --wp) 467*7c478bd9Sstevel@tonic-gate if (_COLOR(*wp) != A_NORMAL) 468*7c478bd9Sstevel@tonic-gate break; 469*7c478bd9Sstevel@tonic-gate if (color_attrx < lastx) 470*7c478bd9Sstevel@tonic-gate color_attrx++; 471*7c478bd9Sstevel@tonic-gate } 472*7c478bd9Sstevel@tonic-gate if (video_attrx < lastx) 473*7c478bd9Sstevel@tonic-gate video_attrx++; 474*7c478bd9Sstevel@tonic-gate 475*7c478bd9Sstevel@tonic-gate if (video_attrx >= scrco) 476*7c478bd9Sstevel@tonic-gate --video_attrx; 477*7c478bd9Sstevel@tonic-gate if (color_marks && color_attrx >= scrco) 478*7c478bd9Sstevel@tonic-gate --color_attrx; 479*7c478bd9Sstevel@tonic-gate if (magic_cookie_glitch > 0 && wy == scrli - 1 && 480*7c478bd9Sstevel@tonic-gate video_attrx == scrco - 1) 481*7c478bd9Sstevel@tonic-gate --video_attrx; 482*7c478bd9Sstevel@tonic-gate if (color_marks && magic_cookie_glitch > 0 && 483*7c478bd9Sstevel@tonic-gate wy == scrli - 1 && color_attrx == scrco - 1) 484*7c478bd9Sstevel@tonic-gate --color_attrx; 485*7c478bd9Sstevel@tonic-gate for (wp = wcp+video_attrx; wp >= wcp+wx; --wp) 486*7c478bd9Sstevel@tonic-gate if (!ISCBIT(*wp)) 487*7c478bd9Sstevel@tonic-gate break; 488*7c478bd9Sstevel@tonic-gate } 489*7c478bd9Sstevel@tonic-gate 490*7c478bd9Sstevel@tonic-gate /* place for insert/delete chars */ 491*7c478bd9Sstevel@tonic-gate #define SLACK 4 492*7c478bd9Sstevel@tonic-gate if (redraw || (!SP->dchok && !SP->ichok) || !(_virtscr->_use_idc) || 493*7c478bd9Sstevel@tonic-gate endns < wx || (endns >= lastx && (scrco - lastx) > SLACK)) { 494*7c478bd9Sstevel@tonic-gate idcx = scrco; 495*7c478bd9Sstevel@tonic-gate } else 496*7c478bd9Sstevel@tonic-gate if (!marks) 497*7c478bd9Sstevel@tonic-gate idcx = -1; 498*7c478bd9Sstevel@tonic-gate else { 499*7c478bd9Sstevel@tonic-gate /* on cookie term, only do idch where no attrs */ 500*7c478bd9Sstevel@tonic-gate /* are used */ 501*7c478bd9Sstevel@tonic-gate for (idcx = scrco - 1, wp = wcp + idcx; idcx >= wx; 502*7c478bd9Sstevel@tonic-gate --idcx, --wp) 503*7c478bd9Sstevel@tonic-gate if (_ATTR(*wp) || _ISMARK1(wy, idcx) || 504*7c478bd9Sstevel@tonic-gate _ISMARK2(wy, idcx)) 505*7c478bd9Sstevel@tonic-gate break; 506*7c478bd9Sstevel@tonic-gate if (idcx >= scrco - SLACK) 507*7c478bd9Sstevel@tonic-gate idcx = scrco; 508*7c478bd9Sstevel@tonic-gate } 509*7c478bd9Sstevel@tonic-gate 510*7c478bd9Sstevel@tonic-gate if (idcx < lastx && endns >= lastx) 511*7c478bd9Sstevel@tonic-gate lastx = scrco; 512*7c478bd9Sstevel@tonic-gate 513*7c478bd9Sstevel@tonic-gate /* max amount of insert allow */ 514*7c478bd9Sstevel@tonic-gate if (idcx == scrco || !SP->ichok) 515*7c478bd9Sstevel@tonic-gate maxi = 0; 516*7c478bd9Sstevel@tonic-gate else 517*7c478bd9Sstevel@tonic-gate if (lastx == scrco) 518*7c478bd9Sstevel@tonic-gate maxi = scrco; 519*7c478bd9Sstevel@tonic-gate else 520*7c478bd9Sstevel@tonic-gate maxi = lastx - (endns + 1); 521*7c478bd9Sstevel@tonic-gate 522*7c478bd9Sstevel@tonic-gate /* go */ 523*7c478bd9Sstevel@tonic-gate wcp += wx; 524*7c478bd9Sstevel@tonic-gate scp += wx; 525*7c478bd9Sstevel@tonic-gate didvideo = changed = FALSE; 526*7c478bd9Sstevel@tonic-gate didcolor = (color_marks) ? FALSE : TRUE; 527*7c478bd9Sstevel@tonic-gate 528*7c478bd9Sstevel@tonic-gate while (wx < lastx) { 529*7c478bd9Sstevel@tonic-gate /* skip things that are already right */ 530*7c478bd9Sstevel@tonic-gate if (!redraw) { 531*7c478bd9Sstevel@tonic-gate multi_col = 0; 532*7c478bd9Sstevel@tonic-gate wx_sav = wx; 533*7c478bd9Sstevel@tonic-gate for (; wx < lastx; ++wx, ++wcp, ++scp) 534*7c478bd9Sstevel@tonic-gate if (*wcp != *scp) 535*7c478bd9Sstevel@tonic-gate break; 536*7c478bd9Sstevel@tonic-gate if (wx >= lastx) 537*7c478bd9Sstevel@tonic-gate goto done; 538*7c478bd9Sstevel@tonic-gate for (; wx > wx_sav; --wx, --wcp, --scp) { 539*7c478bd9Sstevel@tonic-gate if (!ISCBIT(*wcp) && !ISCBIT(*scp)) 540*7c478bd9Sstevel@tonic-gate break; 541*7c478bd9Sstevel@tonic-gate multi_col = 1; 542*7c478bd9Sstevel@tonic-gate } 543*7c478bd9Sstevel@tonic-gate } 544*7c478bd9Sstevel@tonic-gate 545*7c478bd9Sstevel@tonic-gate /* try clear-bol, we'll assume exclusive clr_bol */ 546*7c478bd9Sstevel@tonic-gate if (!changed && !marks && clr_bol && blnkx > wx && 547*7c478bd9Sstevel@tonic-gate begns >= wx) { 548*7c478bd9Sstevel@tonic-gate for (x = wx, wp = wcp; x < lastx; ++x, ++wp) 549*7c478bd9Sstevel@tonic-gate if (_DARKCHAR(*wp)) 550*7c478bd9Sstevel@tonic-gate break; 551*7c478bd9Sstevel@tonic-gate /* clearing only whole screen characters */ 552*7c478bd9Sstevel@tonic-gate for (sp = scp+(x-wx); x >= wx; --x, --sp) 553*7c478bd9Sstevel@tonic-gate if (!ISCBIT(*sp)) 554*7c478bd9Sstevel@tonic-gate break; 555*7c478bd9Sstevel@tonic-gate x -= 1; 556*7c478bd9Sstevel@tonic-gate 557*7c478bd9Sstevel@tonic-gate if ((x - (redraw ? 0 : begns)) > _COST(Clr_bol)) { 558*7c478bd9Sstevel@tonic-gate (void) mvcur(cy, cx, wy, x); 559*7c478bd9Sstevel@tonic-gate /* MORE?: colors - mvcur will shuts of */ 560*7c478bd9Sstevel@tonic-gate /* colors when msgr is not defined */ 561*7c478bd9Sstevel@tonic-gate 562*7c478bd9Sstevel@tonic-gate /* SS: colors */ 563*7c478bd9Sstevel@tonic-gate if (back_color_erase) 564*7c478bd9Sstevel@tonic-gate _turn_off_background(); 565*7c478bd9Sstevel@tonic-gate 566*7c478bd9Sstevel@tonic-gate _PUTS(clr_bol, 1); 567*7c478bd9Sstevel@tonic-gate /* LINTED */ 568*7c478bd9Sstevel@tonic-gate cy = (short) wy; 569*7c478bd9Sstevel@tonic-gate /* LINTED */ 570*7c478bd9Sstevel@tonic-gate cx = (short) x; 571*7c478bd9Sstevel@tonic-gate 572*7c478bd9Sstevel@tonic-gate mtch = x - wx; 573*7c478bd9Sstevel@tonic-gate (void) memcpy((char *) scp, (char *) wcp, 574*7c478bd9Sstevel@tonic-gate (mtch * sizeof (chtype))); 575*7c478bd9Sstevel@tonic-gate wcp += mtch; 576*7c478bd9Sstevel@tonic-gate scp += mtch; 577*7c478bd9Sstevel@tonic-gate wx = x; 578*7c478bd9Sstevel@tonic-gate } 579*7c478bd9Sstevel@tonic-gate } 580*7c478bd9Sstevel@tonic-gate 581*7c478bd9Sstevel@tonic-gate /* screen image is changing */ 582*7c478bd9Sstevel@tonic-gate changed = TRUE; 583*7c478bd9Sstevel@tonic-gate 584*7c478bd9Sstevel@tonic-gate /* move to the point to start refresh */ 585*7c478bd9Sstevel@tonic-gate if (cy != wy || cx != wx) 586*7c478bd9Sstevel@tonic-gate (void) mvcur(cy, cx, wy, wx); 587*7c478bd9Sstevel@tonic-gate /* LINTED */ 588*7c478bd9Sstevel@tonic-gate cy = (short) wy; 589*7c478bd9Sstevel@tonic-gate /* LINTED */ 590*7c478bd9Sstevel@tonic-gate cx = (short) wx; 591*7c478bd9Sstevel@tonic-gate 592*7c478bd9Sstevel@tonic-gate /* update screen image */ 593*7c478bd9Sstevel@tonic-gate while (wx < lastx) { 594*7c478bd9Sstevel@tonic-gate wc = *wcp; 595*7c478bd9Sstevel@tonic-gate sc = *scp; 596*7c478bd9Sstevel@tonic-gate 597*7c478bd9Sstevel@tonic-gate if (!redraw && !multi_col && wc == sc) 598*7c478bd9Sstevel@tonic-gate break; 599*7c478bd9Sstevel@tonic-gate 600*7c478bd9Sstevel@tonic-gate /* real video attributes */ 601*7c478bd9Sstevel@tonic-gate if (marks) 602*7c478bd9Sstevel@tonic-gate curscr->_attrs = _ATTR(sc); 603*7c478bd9Sstevel@tonic-gate 604*7c478bd9Sstevel@tonic-gate /* blanks only */ 605*7c478bd9Sstevel@tonic-gate if (wx > blnkx) { 606*7c478bd9Sstevel@tonic-gate /* SS: colors */ 607*7c478bd9Sstevel@tonic-gate if (back_color_erase) 608*7c478bd9Sstevel@tonic-gate _turn_off_background(); 609*7c478bd9Sstevel@tonic-gate 610*7c478bd9Sstevel@tonic-gate _PUTS(clr_eol, 1); 611*7c478bd9Sstevel@tonic-gate /* LINTED */ 612*7c478bd9Sstevel@tonic-gate curscr->_curx = (short) wx; 613*7c478bd9Sstevel@tonic-gate /* LINTED */ 614*7c478bd9Sstevel@tonic-gate curscr->_cury = (short) wy; 615*7c478bd9Sstevel@tonic-gate (void) wclrtoeol(curscr); 616*7c478bd9Sstevel@tonic-gate 617*7c478bd9Sstevel@tonic-gate if (marks && wx > 0 && _ATTR(*(scp - 1)) != 618*7c478bd9Sstevel@tonic-gate A_NORMAL) { 619*7c478bd9Sstevel@tonic-gate _VIDS(A_NORMAL, _ATTR(*(scp - 1))); 620*7c478bd9Sstevel@tonic-gate if (_VIDEO(*scp - 1)) 621*7c478bd9Sstevel@tonic-gate _setmark1(wy, wx, NULL); 622*7c478bd9Sstevel@tonic-gate if (_COLOR(*scp - 1)) 623*7c478bd9Sstevel@tonic-gate _setmark2(wy, wx, NULL); 624*7c478bd9Sstevel@tonic-gate } 625*7c478bd9Sstevel@tonic-gate goto done; 626*7c478bd9Sstevel@tonic-gate } 627*7c478bd9Sstevel@tonic-gate 628*7c478bd9Sstevel@tonic-gate /* try insert/delete chars */ 629*7c478bd9Sstevel@tonic-gate if (wx > idcx && !ISCBIT(*scp) && 630*7c478bd9Sstevel@tonic-gate (mtch = _useidch(wcp, scp, lastx - wx, 631*7c478bd9Sstevel@tonic-gate maxi, &idch))) { 632*7c478bd9Sstevel@tonic-gate maxi -= idch; 633*7c478bd9Sstevel@tonic-gate wx += mtch; 634*7c478bd9Sstevel@tonic-gate scp += mtch; 635*7c478bd9Sstevel@tonic-gate wcp += mtch; 636*7c478bd9Sstevel@tonic-gate break; 637*7c478bd9Sstevel@tonic-gate } 638*7c478bd9Sstevel@tonic-gate 639*7c478bd9Sstevel@tonic-gate /* about to output chars, make sure insert */ 640*7c478bd9Sstevel@tonic-gate /* mode is off */ 641*7c478bd9Sstevel@tonic-gate if (SP->phys_irm) 642*7c478bd9Sstevel@tonic-gate _OFFINSERT(); 643*7c478bd9Sstevel@tonic-gate 644*7c478bd9Sstevel@tonic-gate /* color and video attributes */ 645*7c478bd9Sstevel@tonic-gate if (_ATTR(wc) != curscr->_attrs) { 646*7c478bd9Sstevel@tonic-gate bool color_change = FALSE; 647*7c478bd9Sstevel@tonic-gate bool video_change = FALSE; 648*7c478bd9Sstevel@tonic-gate 649*7c478bd9Sstevel@tonic-gate if (marks) 650*7c478bd9Sstevel@tonic-gate if (_VIDEO(wc) != _VIDEO(curscr->_attrs)) 651*7c478bd9Sstevel@tonic-gate video_change = TRUE; 652*7c478bd9Sstevel@tonic-gate if (color_marks) 653*7c478bd9Sstevel@tonic-gate if (_COLOR(wc) != _COLOR(curscr->_attrs)) 654*7c478bd9Sstevel@tonic-gate color_change = TRUE; 655*7c478bd9Sstevel@tonic-gate 656*7c478bd9Sstevel@tonic-gate /* the following may occurs when, for */ 657*7c478bd9Sstevel@tonic-gate /* example the application */ 658*7c478bd9Sstevel@tonic-gate /* is written for color terminal and then */ 659*7c478bd9Sstevel@tonic-gate /* run on a monocrome */ 660*7c478bd9Sstevel@tonic-gate 661*7c478bd9Sstevel@tonic-gate if (marks && !video_change && !color_change) 662*7c478bd9Sstevel@tonic-gate goto no_change; 663*7c478bd9Sstevel@tonic-gate 664*7c478bd9Sstevel@tonic-gate /* prevent spilling out of line */ 665*7c478bd9Sstevel@tonic-gate if (marks && !(didcolor && didvideo)) { 666*7c478bd9Sstevel@tonic-gate if ((video_change && !_ISMARK1(wy, 667*7c478bd9Sstevel@tonic-gate video_attrx)) || (color_change && 668*7c478bd9Sstevel@tonic-gate !_ISMARK2(wy, color_attrx))) { 669*7c478bd9Sstevel@tonic-gate int tempx; 670*7c478bd9Sstevel@tonic-gate chtype sa = curscr->_attrs; 671*7c478bd9Sstevel@tonic-gate bool first = FALSE; 672*7c478bd9Sstevel@tonic-gate bool second = FALSE; 673*7c478bd9Sstevel@tonic-gate 674*7c478bd9Sstevel@tonic-gate if (!didvideo && video_change && 675*7c478bd9Sstevel@tonic-gate !_ISMARK1(wy, video_attrx)) { 676*7c478bd9Sstevel@tonic-gate didvideo = TRUE; 677*7c478bd9Sstevel@tonic-gate (void) mvcur(wy, wx, 678*7c478bd9Sstevel@tonic-gate wy, video_attrx); 679*7c478bd9Sstevel@tonic-gate _VIDS(_VIDEO(_virtscr->_y[wy] 680*7c478bd9Sstevel@tonic-gate [video_attrx]), 681*7c478bd9Sstevel@tonic-gate _VIDEO(_virtscr->_y[wy] 682*7c478bd9Sstevel@tonic-gate [video_attrx-1])); 683*7c478bd9Sstevel@tonic-gate _setmark1(wy, video_attrx, 684*7c478bd9Sstevel@tonic-gate NULL); 685*7c478bd9Sstevel@tonic-gate first = TRUE; 686*7c478bd9Sstevel@tonic-gate } 687*7c478bd9Sstevel@tonic-gate 688*7c478bd9Sstevel@tonic-gate if (!didcolor && color_change && 689*7c478bd9Sstevel@tonic-gate !_ISMARK2(wy, color_attrx)) { 690*7c478bd9Sstevel@tonic-gate didcolor = TRUE; 691*7c478bd9Sstevel@tonic-gate tempx = first ? video_attrx : wx; 692*7c478bd9Sstevel@tonic-gate if (tempx != color_attrx) 693*7c478bd9Sstevel@tonic-gate (void) mvcur(wy, tempx, wy, 694*7c478bd9Sstevel@tonic-gate color_attrx); 695*7c478bd9Sstevel@tonic-gate /* 696*7c478bd9Sstevel@tonic-gate * sc = _COLOR(curscr->_y[wy][color_attrx]); 697*7c478bd9Sstevel@tonic-gate *_VIDS(sc, (~sc & A_COLOR)); 698*7c478bd9Sstevel@tonic-gate */ 699*7c478bd9Sstevel@tonic-gate _VIDS(_COLOR(_virtscr->_y[wy] 700*7c478bd9Sstevel@tonic-gate [color_attrx]), 701*7c478bd9Sstevel@tonic-gate _COLOR(_virtscr->_y[wy] 702*7c478bd9Sstevel@tonic-gate [color_attrx-1])); 703*7c478bd9Sstevel@tonic-gate _setmark2(wy, color_attrx, NULL); 704*7c478bd9Sstevel@tonic-gate second = TRUE; 705*7c478bd9Sstevel@tonic-gate } 706*7c478bd9Sstevel@tonic-gate (void) mvcur(wy, (second ? color_attrx : 707*7c478bd9Sstevel@tonic-gate video_attrx), wy, wx); 708*7c478bd9Sstevel@tonic-gate curscr->_attrs = sa; 709*7c478bd9Sstevel@tonic-gate } 710*7c478bd9Sstevel@tonic-gate } 711*7c478bd9Sstevel@tonic-gate 712*7c478bd9Sstevel@tonic-gate _VIDS(_ATTR(wc), curscr->_attrs); 713*7c478bd9Sstevel@tonic-gate 714*7c478bd9Sstevel@tonic-gate /* on cookie terminals mark the interval */ 715*7c478bd9Sstevel@tonic-gate if (video_change) 716*7c478bd9Sstevel@tonic-gate _setmark1(wy, wx, scp); 717*7c478bd9Sstevel@tonic-gate if (color_change) 718*7c478bd9Sstevel@tonic-gate _setmark2(wy, wx, scp); 719*7c478bd9Sstevel@tonic-gate } 720*7c478bd9Sstevel@tonic-gate 721*7c478bd9Sstevel@tonic-gate /* end-of-line */ 722*7c478bd9Sstevel@tonic-gate no_change: 723*7c478bd9Sstevel@tonic-gate x = 1; 724*7c478bd9Sstevel@tonic-gate if (_scrmax > 1) 725*7c478bd9Sstevel@tonic-gate x = _curs_scrwidth[TYPE(RBYTE(wc))]; 726*7c478bd9Sstevel@tonic-gate if (wx == scrco - x) { 727*7c478bd9Sstevel@tonic-gate _rmargin(wx); 728*7c478bd9Sstevel@tonic-gate goto done; 729*7c478bd9Sstevel@tonic-gate } 730*7c478bd9Sstevel@tonic-gate 731*7c478bd9Sstevel@tonic-gate if (transparent_underline && erase_overstrike && 732*7c478bd9Sstevel@tonic-gate _CHAR(wc) == '_') { 733*7c478bd9Sstevel@tonic-gate (void) _outch(' '); 734*7c478bd9Sstevel@tonic-gate (void) mvcur(wy, wx + 1, wy, wx); 735*7c478bd9Sstevel@tonic-gate } 736*7c478bd9Sstevel@tonic-gate 737*7c478bd9Sstevel@tonic-gate /* put out the character */ 738*7c478bd9Sstevel@tonic-gate (void) _outwch(tilde_glitch && _CHAR(wc) == '~' ? '`' : wc); 739*7c478bd9Sstevel@tonic-gate 740*7c478bd9Sstevel@tonic-gate *scp++ = wc; 741*7c478bd9Sstevel@tonic-gate wcp++; 742*7c478bd9Sstevel@tonic-gate wx++; 743*7c478bd9Sstevel@tonic-gate cx++; 744*7c478bd9Sstevel@tonic-gate /* output entire multi-byte chars */ 745*7c478bd9Sstevel@tonic-gate while (wx < lastx && ISCBIT(*wcp)) { 746*7c478bd9Sstevel@tonic-gate (void) _outwch(*wcp); 747*7c478bd9Sstevel@tonic-gate *scp++ = *wcp++; 748*7c478bd9Sstevel@tonic-gate wx++; 749*7c478bd9Sstevel@tonic-gate cx++; 750*7c478bd9Sstevel@tonic-gate 751*7c478bd9Sstevel@tonic-gate 752*7c478bd9Sstevel@tonic-gate 753*7c478bd9Sstevel@tonic-gate 754*7c478bd9Sstevel@tonic-gate } 755*7c478bd9Sstevel@tonic-gate } 756*7c478bd9Sstevel@tonic-gate } 757*7c478bd9Sstevel@tonic-gate 758*7c478bd9Sstevel@tonic-gate done: 759*7c478bd9Sstevel@tonic-gate if (changed) { 760*7c478bd9Sstevel@tonic-gate /* update the blank structure */ 761*7c478bd9Sstevel@tonic-gate for (wx = 0, scp = curscr->_y[wy]; wx < scrco; ++wx, ++scp) 762*7c478bd9Sstevel@tonic-gate if (_DARKCHAR(*scp)) 763*7c478bd9Sstevel@tonic-gate break; 764*7c478bd9Sstevel@tonic-gate /* LINTED */ 765*7c478bd9Sstevel@tonic-gate _BEGNS[wy] = (short) wx; 766*7c478bd9Sstevel@tonic-gate if (wx == scrco) 767*7c478bd9Sstevel@tonic-gate _ENDNS[wy] = -1; 768*7c478bd9Sstevel@tonic-gate else { 769*7c478bd9Sstevel@tonic-gate wx = scrco - 1; 770*7c478bd9Sstevel@tonic-gate scp = curscr->_y[wy] + wx; 771*7c478bd9Sstevel@tonic-gate for (; wx >= 0; --wx, --scp) 772*7c478bd9Sstevel@tonic-gate if (_DARKCHAR(*scp)) 773*7c478bd9Sstevel@tonic-gate break; 774*7c478bd9Sstevel@tonic-gate /* LINTED */ 775*7c478bd9Sstevel@tonic-gate _ENDNS[wy] = (short) wx; 776*7c478bd9Sstevel@tonic-gate } 777*7c478bd9Sstevel@tonic-gate 778*7c478bd9Sstevel@tonic-gate /* update the hash structure */ 779*7c478bd9Sstevel@tonic-gate _CURHASH[wy] = _BEGNS[wy] < scrco ? _NOHASH : 0; 780*7c478bd9Sstevel@tonic-gate } 781*7c478bd9Sstevel@tonic-gate } 782*7c478bd9Sstevel@tonic-gate 783*7c478bd9Sstevel@tonic-gate /* 784*7c478bd9Sstevel@tonic-gate * See if a left or right shift is apppropriate 785*7c478bd9Sstevel@tonic-gate * This routine is called only if !cookie_glitch or no video attributes 786*7c478bd9Sstevel@tonic-gate * are used in the affected part. 787*7c478bd9Sstevel@tonic-gate * The main idea is to find a longest common substring which is a 788*7c478bd9Sstevel@tonic-gate * prefix of one of 'wcp' or 'scp', then either delete or 789*7c478bd9Sstevel@tonic-gate * insert depending on where the prefix is. 790*7c478bd9Sstevel@tonic-gate * 791*7c478bd9Sstevel@tonic-gate * wcp : what we want the screen to look like 792*7c478bd9Sstevel@tonic-gate * scp : what the screen looks like now 793*7c478bd9Sstevel@tonic-gate * length: the length to be updated 794*7c478bd9Sstevel@tonic-gate * maxi: maximum possible insert amount 795*7c478bd9Sstevel@tonic-gate * id; *id returns the amount of insert/delete 796*7c478bd9Sstevel@tonic-gate * 797*7c478bd9Sstevel@tonic-gate * Return the number of chars matched after the shift. 798*7c478bd9Sstevel@tonic-gate */ 799*7c478bd9Sstevel@tonic-gate 800*7c478bd9Sstevel@tonic-gate static int 801*7c478bd9Sstevel@tonic-gate _useidch(chtype *wcp, chtype *scp, int length, int maxi, int *id) 802*7c478bd9Sstevel@tonic-gate { 803*7c478bd9Sstevel@tonic-gate int x1, x2, blnk, idch, cost, cost_ich1, match; 804*7c478bd9Sstevel@tonic-gate chtype wc; 805*7c478bd9Sstevel@tonic-gate 806*7c478bd9Sstevel@tonic-gate /* try deletion */ 807*7c478bd9Sstevel@tonic-gate if (SP->dchok && _CHAR(*wcp) != ' ') { 808*7c478bd9Sstevel@tonic-gate if ((match = _prefix(wcp, scp, length, length / 2, &idch)) > 0) 809*7c478bd9Sstevel@tonic-gate cost = _COST(dcfixed) + (parm_dch ? _COST(Parm_dch) : 810*7c478bd9Sstevel@tonic-gate _COST(Delete_character) * idch); 811*7c478bd9Sstevel@tonic-gate else 812*7c478bd9Sstevel@tonic-gate cost = _INFINITY; 813*7c478bd9Sstevel@tonic-gate 814*7c478bd9Sstevel@tonic-gate if (match >= cost) { 815*7c478bd9Sstevel@tonic-gate /* SS: colors */ 816*7c478bd9Sstevel@tonic-gate if (back_color_erase) 817*7c478bd9Sstevel@tonic-gate _turn_off_background(); 818*7c478bd9Sstevel@tonic-gate 819*7c478bd9Sstevel@tonic-gate if (SP->dmode) { 820*7c478bd9Sstevel@tonic-gate if (SP->sid_equal) { 821*7c478bd9Sstevel@tonic-gate if (!(SP->phys_irm)) 822*7c478bd9Sstevel@tonic-gate _ONINSERT(); 823*7c478bd9Sstevel@tonic-gate } else { 824*7c478bd9Sstevel@tonic-gate if (SP->phys_irm) 825*7c478bd9Sstevel@tonic-gate _OFFINSERT(); 826*7c478bd9Sstevel@tonic-gate _PUTS(enter_delete_mode, 1); 827*7c478bd9Sstevel@tonic-gate } 828*7c478bd9Sstevel@tonic-gate } 829*7c478bd9Sstevel@tonic-gate 830*7c478bd9Sstevel@tonic-gate if (parm_dch) 831*7c478bd9Sstevel@tonic-gate _PUTS(tparm_p1(parm_dch, idch), 1); 832*7c478bd9Sstevel@tonic-gate else 833*7c478bd9Sstevel@tonic-gate for (x1 = 0; x1 < idch; ++x1) 834*7c478bd9Sstevel@tonic-gate _PUTS(delete_character, 1); 835*7c478bd9Sstevel@tonic-gate 836*7c478bd9Sstevel@tonic-gate if (SP->dmode) { 837*7c478bd9Sstevel@tonic-gate if (SP->eid_equal) 838*7c478bd9Sstevel@tonic-gate SP->phys_irm = FALSE; 839*7c478bd9Sstevel@tonic-gate _PUTS(exit_delete_mode, 1); 840*7c478bd9Sstevel@tonic-gate } 841*7c478bd9Sstevel@tonic-gate 842*7c478bd9Sstevel@tonic-gate /* update screen image */ 843*7c478bd9Sstevel@tonic-gate for (x1 = 0, x2 = idch; x2 < length; ++x1, ++x2) 844*7c478bd9Sstevel@tonic-gate scp[x1] = scp[x2]; 845*7c478bd9Sstevel@tonic-gate for (; x1 < length; ++x1) 846*7c478bd9Sstevel@tonic-gate scp[x1] = ' '; 847*7c478bd9Sstevel@tonic-gate 848*7c478bd9Sstevel@tonic-gate *id = -idch; 849*7c478bd9Sstevel@tonic-gate return (match); 850*7c478bd9Sstevel@tonic-gate } 851*7c478bd9Sstevel@tonic-gate } 852*7c478bd9Sstevel@tonic-gate 853*7c478bd9Sstevel@tonic-gate /* no insertion wanted or possible */ 854*7c478bd9Sstevel@tonic-gate if (!(SP->ichok) || _CHAR(*scp) == ' ') 855*7c478bd9Sstevel@tonic-gate return (0); 856*7c478bd9Sstevel@tonic-gate 857*7c478bd9Sstevel@tonic-gate /* see if insertion is worth it */ 858*7c478bd9Sstevel@tonic-gate maxi = (idch = length / 2) < maxi ? idch : maxi; 859*7c478bd9Sstevel@tonic-gate if ((match = _prefix(scp, wcp, length, maxi, &idch)) <= 0) 860*7c478bd9Sstevel@tonic-gate return (0); 861*7c478bd9Sstevel@tonic-gate 862*7c478bd9Sstevel@tonic-gate /* see if inserting blanks only */ 863*7c478bd9Sstevel@tonic-gate for (blnk = 0; blnk < idch; ++blnk) 864*7c478bd9Sstevel@tonic-gate if (wcp[blnk] != ' ') { 865*7c478bd9Sstevel@tonic-gate blnk = 0; 866*7c478bd9Sstevel@tonic-gate break; 867*7c478bd9Sstevel@tonic-gate } 868*7c478bd9Sstevel@tonic-gate 869*7c478bd9Sstevel@tonic-gate /* see if doing insertion is worth it */ 870*7c478bd9Sstevel@tonic-gate cost_ich1 = idch * _COST(Insert_character); 871*7c478bd9Sstevel@tonic-gate if (SP->imode) { 872*7c478bd9Sstevel@tonic-gate cost = SP->phys_irm ? 0 : _COST(icfixed); 873*7c478bd9Sstevel@tonic-gate if (blnk > _COST(Parm_ich) && _COST(Parm_ich) < cost_ich1) 874*7c478bd9Sstevel@tonic-gate cost += _COST(Parm_ich); 875*7c478bd9Sstevel@tonic-gate else 876*7c478bd9Sstevel@tonic-gate if (insert_character) 877*7c478bd9Sstevel@tonic-gate cost += cost_ich1; 878*7c478bd9Sstevel@tonic-gate } else { 879*7c478bd9Sstevel@tonic-gate if (parm_ich && _COST(Parm_ich) < cost_ich1) 880*7c478bd9Sstevel@tonic-gate cost = _COST(Parm_ich); 881*7c478bd9Sstevel@tonic-gate else 882*7c478bd9Sstevel@tonic-gate cost = cost_ich1; 883*7c478bd9Sstevel@tonic-gate } 884*7c478bd9Sstevel@tonic-gate if ((cost - blnk) > match) 885*7c478bd9Sstevel@tonic-gate return (0); 886*7c478bd9Sstevel@tonic-gate 887*7c478bd9Sstevel@tonic-gate /* perform the insertions */ 888*7c478bd9Sstevel@tonic-gate 889*7c478bd9Sstevel@tonic-gate /* SS: colors */ 890*7c478bd9Sstevel@tonic-gate if (back_color_erase) 891*7c478bd9Sstevel@tonic-gate _turn_off_background(); 892*7c478bd9Sstevel@tonic-gate 893*7c478bd9Sstevel@tonic-gate if (SP->imode) { 894*7c478bd9Sstevel@tonic-gate if (!SP->phys_irm) 895*7c478bd9Sstevel@tonic-gate _ONINSERT(); 896*7c478bd9Sstevel@tonic-gate if (blnk > _COST(Parm_ich) && _COST(Parm_ich) < cost_ich1) 897*7c478bd9Sstevel@tonic-gate _PUTS(tparm_p1(parm_ich, idch), 1); 898*7c478bd9Sstevel@tonic-gate else 899*7c478bd9Sstevel@tonic-gate if (insert_character) 900*7c478bd9Sstevel@tonic-gate goto do_insert_char; 901*7c478bd9Sstevel@tonic-gate else 902*7c478bd9Sstevel@tonic-gate /* so that we'll do real char insertions */ 903*7c478bd9Sstevel@tonic-gate blnk = 0; 904*7c478bd9Sstevel@tonic-gate } else { 905*7c478bd9Sstevel@tonic-gate if (parm_ich && _COST(Parm_ich) < cost_ich1) 906*7c478bd9Sstevel@tonic-gate _PUTS(tparm_p1(parm_ich, idch), 1); 907*7c478bd9Sstevel@tonic-gate else { 908*7c478bd9Sstevel@tonic-gate do_insert_char: 909*7c478bd9Sstevel@tonic-gate for (x1 = 0; x1 < idch; ++x1) 910*7c478bd9Sstevel@tonic-gate _PUTS(insert_character, 1); 911*7c478bd9Sstevel@tonic-gate } 912*7c478bd9Sstevel@tonic-gate } 913*7c478bd9Sstevel@tonic-gate 914*7c478bd9Sstevel@tonic-gate /* inserting desired characters */ 915*7c478bd9Sstevel@tonic-gate if (!blnk) 916*7c478bd9Sstevel@tonic-gate for (x1 = 0; x1 < idch; ++x1) { 917*7c478bd9Sstevel@tonic-gate wc = wcp[x1]; 918*7c478bd9Sstevel@tonic-gate if (_ATTR(wc) != curscr->_attrs) 919*7c478bd9Sstevel@tonic-gate _VIDS(_ATTR(wc), curscr->_attrs); 920*7c478bd9Sstevel@tonic-gate (void) _outwch(_CHAR(wc) == '~' && 921*7c478bd9Sstevel@tonic-gate tilde_glitch ? '`' : wc); 922*7c478bd9Sstevel@tonic-gate ++cx; 923*7c478bd9Sstevel@tonic-gate } 924*7c478bd9Sstevel@tonic-gate 925*7c478bd9Sstevel@tonic-gate /* update the screen image */ 926*7c478bd9Sstevel@tonic-gate for (x1 = length - 1, x2 = length - idch - 1; x2 >= 0; --x1, --x2) 927*7c478bd9Sstevel@tonic-gate scp[x1] = scp[x2]; 928*7c478bd9Sstevel@tonic-gate (void) memcpy((char *) scp, (char *) wcp, idch * sizeof (chtype)); 929*7c478bd9Sstevel@tonic-gate 930*7c478bd9Sstevel@tonic-gate *id = idch; 931*7c478bd9Sstevel@tonic-gate return (match + idch); 932*7c478bd9Sstevel@tonic-gate } 933*7c478bd9Sstevel@tonic-gate 934*7c478bd9Sstevel@tonic-gate /* 935*7c478bd9Sstevel@tonic-gate * Find a substring of s2 that match a prefix of s1. 936*7c478bd9Sstevel@tonic-gate * The substring is such that: 937*7c478bd9Sstevel@tonic-gate * 1. it does not start with an element 938*7c478bd9Sstevel@tonic-gate * that is in perfect alignment with one in s1 and 939*7c478bd9Sstevel@tonic-gate * 2: it is at least as long as the displacement. 940*7c478bd9Sstevel@tonic-gate * 941*7c478bd9Sstevel@tonic-gate * length: the length of s1, s2. 942*7c478bd9Sstevel@tonic-gate * maxs: only search for match in [1,maxs] of s2. 943*7c478bd9Sstevel@tonic-gate * begm: *begm returns where the match begins. 944*7c478bd9Sstevel@tonic-gate * 945*7c478bd9Sstevel@tonic-gate * Return the number of matches. 946*7c478bd9Sstevel@tonic-gate */ 947*7c478bd9Sstevel@tonic-gate 948*7c478bd9Sstevel@tonic-gate static int 949*7c478bd9Sstevel@tonic-gate _prefix(chtype *s1, chtype *s2, int length, int maxs, int *begm) 950*7c478bd9Sstevel@tonic-gate { 951*7c478bd9Sstevel@tonic-gate int m, n, k; 952*7c478bd9Sstevel@tonic-gate 953*7c478bd9Sstevel@tonic-gate n = 0; 954*7c478bd9Sstevel@tonic-gate for (m = 1; m <= maxs; ++m) 955*7c478bd9Sstevel@tonic-gate /* testing for s1[m] != s2[m] is condition 1 */ 956*7c478bd9Sstevel@tonic-gate if (s1[0] == s2[m] && s1[m] != s2[m]) { 957*7c478bd9Sstevel@tonic-gate /* see if it's long enough (condition 2) */ 958*7c478bd9Sstevel@tonic-gate for (k = 2 * m - 1; k > m; --k) 959*7c478bd9Sstevel@tonic-gate if (s1[k - m] != s2[k]) 960*7c478bd9Sstevel@tonic-gate break; 961*7c478bd9Sstevel@tonic-gate /* found a match with a good length */ 962*7c478bd9Sstevel@tonic-gate if (k == m) { 963*7c478bd9Sstevel@tonic-gate *begm = m; 964*7c478bd9Sstevel@tonic-gate 965*7c478bd9Sstevel@tonic-gate /* count the # of matches */ 966*7c478bd9Sstevel@tonic-gate s2 += m; 967*7c478bd9Sstevel@tonic-gate length -= m; 968*7c478bd9Sstevel@tonic-gate for (n = m; n < length; ++n) 969*7c478bd9Sstevel@tonic-gate if (s1[n] != s2[n]) 970*7c478bd9Sstevel@tonic-gate break; 971*7c478bd9Sstevel@tonic-gate goto done; 972*7c478bd9Sstevel@tonic-gate } 973*7c478bd9Sstevel@tonic-gate } 974*7c478bd9Sstevel@tonic-gate 975*7c478bd9Sstevel@tonic-gate done: 976*7c478bd9Sstevel@tonic-gate return (n); 977*7c478bd9Sstevel@tonic-gate } 978*7c478bd9Sstevel@tonic-gate 979*7c478bd9Sstevel@tonic-gate /* Set video markers for cookie terminal. */ 980*7c478bd9Sstevel@tonic-gate 981*7c478bd9Sstevel@tonic-gate static void 982*7c478bd9Sstevel@tonic-gate _setmark1(int y, int x, chtype *s) 983*7c478bd9Sstevel@tonic-gate { 984*7c478bd9Sstevel@tonic-gate long a; 985*7c478bd9Sstevel@tonic-gate 986*7c478bd9Sstevel@tonic-gate /* set the mark map */ 987*7c478bd9Sstevel@tonic-gate marks[y][x / BITSPERBYTE] |= (1 << (x % BITSPERBYTE)); 988*7c478bd9Sstevel@tonic-gate 989*7c478bd9Sstevel@tonic-gate if (s) { 990*7c478bd9Sstevel@tonic-gate a = _VIDEO(curscr->_attrs); 991*7c478bd9Sstevel@tonic-gate 992*7c478bd9Sstevel@tonic-gate /* set the video attr of the first char here */ 993*7c478bd9Sstevel@tonic-gate /* LINTED */ 994*7c478bd9Sstevel@tonic-gate *s = _CHAR(*s) | _COLOR(*s) | a; 995*7c478bd9Sstevel@tonic-gate 996*7c478bd9Sstevel@tonic-gate /* now the video attr of the rest of the affected interval */ 997*7c478bd9Sstevel@tonic-gate for (x += 1, s += 1; x < scrco; ++x, ++s) 998*7c478bd9Sstevel@tonic-gate if (_ISMARK1(y, x)) 999*7c478bd9Sstevel@tonic-gate break; 1000*7c478bd9Sstevel@tonic-gate else 1001*7c478bd9Sstevel@tonic-gate /* LINTED */ 1002*7c478bd9Sstevel@tonic-gate *s = _CHAR(*s) | _COLOR(*s) | a; 1003*7c478bd9Sstevel@tonic-gate } 1004*7c478bd9Sstevel@tonic-gate } 1005*7c478bd9Sstevel@tonic-gate 1006*7c478bd9Sstevel@tonic-gate /* Set color markers for cookie terminal. */ 1007*7c478bd9Sstevel@tonic-gate 1008*7c478bd9Sstevel@tonic-gate static void 1009*7c478bd9Sstevel@tonic-gate _setmark2(int y, int x, chtype *s) 1010*7c478bd9Sstevel@tonic-gate { 1011*7c478bd9Sstevel@tonic-gate long a; 1012*7c478bd9Sstevel@tonic-gate 1013*7c478bd9Sstevel@tonic-gate /* set the mark map */ 1014*7c478bd9Sstevel@tonic-gate color_marks[y][x / BITSPERBYTE] |= (1 << (x % BITSPERBYTE)); 1015*7c478bd9Sstevel@tonic-gate 1016*7c478bd9Sstevel@tonic-gate if (s) { 1017*7c478bd9Sstevel@tonic-gate a = _COLOR(curscr->_attrs); 1018*7c478bd9Sstevel@tonic-gate 1019*7c478bd9Sstevel@tonic-gate /* set the video attr of the first char here */ 1020*7c478bd9Sstevel@tonic-gate /* LINTED */ 1021*7c478bd9Sstevel@tonic-gate *s = _CHAR(*s) | _VIDEO(*s) | a; 1022*7c478bd9Sstevel@tonic-gate 1023*7c478bd9Sstevel@tonic-gate /* now the video attr of the rest of the affected interval */ 1024*7c478bd9Sstevel@tonic-gate for (x += 1, s += 1; x < scrco; ++x, ++s) 1025*7c478bd9Sstevel@tonic-gate if (_ISMARK2(y, x)) 1026*7c478bd9Sstevel@tonic-gate break; 1027*7c478bd9Sstevel@tonic-gate else 1028*7c478bd9Sstevel@tonic-gate /* LINTED */ 1029*7c478bd9Sstevel@tonic-gate *s = _CHAR(*s) | _VIDEO(*s) | a; 1030*7c478bd9Sstevel@tonic-gate } 1031*7c478bd9Sstevel@tonic-gate } 1032*7c478bd9Sstevel@tonic-gate 1033*7c478bd9Sstevel@tonic-gate 1034*7c478bd9Sstevel@tonic-gate /* At the right margin various weird things can happen. We treat them here. */ 1035*7c478bd9Sstevel@tonic-gate 1036*7c478bd9Sstevel@tonic-gate /* At the right margin various weird things can happen. We treat them here. */ 1037*7c478bd9Sstevel@tonic-gate 1038*7c478bd9Sstevel@tonic-gate static void 1039*7c478bd9Sstevel@tonic-gate _rmargin(int wx) 1040*7c478bd9Sstevel@tonic-gate { 1041*7c478bd9Sstevel@tonic-gate int x, w, ix; 1042*7c478bd9Sstevel@tonic-gate chtype sc; 1043*7c478bd9Sstevel@tonic-gate chtype *wcp = _virtscr->_y[cy]; 1044*7c478bd9Sstevel@tonic-gate 1045*7c478bd9Sstevel@tonic-gate /* screen may scroll */ 1046*7c478bd9Sstevel@tonic-gate if (cy == scrli - 1) { 1047*7c478bd9Sstevel@tonic-gate /* can't do anything */ 1048*7c478bd9Sstevel@tonic-gate if (!SP->ichok) 1049*7c478bd9Sstevel@tonic-gate return; 1050*7c478bd9Sstevel@tonic-gate 1051*7c478bd9Sstevel@tonic-gate /* the width of the new character */ 1052*7c478bd9Sstevel@tonic-gate w = _curs_scrwidth[TYPE(RBYTE(wcp[wx]))]; 1053*7c478bd9Sstevel@tonic-gate /* the place to put it without causing scrolling */ 1054*7c478bd9Sstevel@tonic-gate for (x = wx - 1; x > 0; --x) 1055*7c478bd9Sstevel@tonic-gate if (!ISCBIT(wcp[x])) 1056*7c478bd9Sstevel@tonic-gate break; 1057*7c478bd9Sstevel@tonic-gate sc = curscr->_y[cy][x]; 1058*7c478bd9Sstevel@tonic-gate 1059*7c478bd9Sstevel@tonic-gate (void) mvcur(cy, cx, cy, x); 1060*7c478bd9Sstevel@tonic-gate if (_ATTR(wcp[wx]) != curscr->_attrs) 1061*7c478bd9Sstevel@tonic-gate _VIDS(_ATTR(wcp[wx]), curscr->_attrs); 1062*7c478bd9Sstevel@tonic-gate (void) _outwch(tilde_glitch && 1063*7c478bd9Sstevel@tonic-gate _CHAR(wcp[wx]) == '~' ? '`' : wcp[wx]); 1064*7c478bd9Sstevel@tonic-gate 1065*7c478bd9Sstevel@tonic-gate for (ix = wx + 1; ix < scrco; ++ix) { 1066*7c478bd9Sstevel@tonic-gate (void) _outwch(wcp[ix]); 1067*7c478bd9Sstevel@tonic-gate } 1068*7c478bd9Sstevel@tonic-gate 1069*7c478bd9Sstevel@tonic-gate /* insert sc back in and push wcp[wx] right */ 1070*7c478bd9Sstevel@tonic-gate (void) mvcur(cy, x+w, cy, x); 1071*7c478bd9Sstevel@tonic-gate 1072*7c478bd9Sstevel@tonic-gate /* SS: colors */ 1073*7c478bd9Sstevel@tonic-gate if (back_color_erase) 1074*7c478bd9Sstevel@tonic-gate _turn_off_background(); 1075*7c478bd9Sstevel@tonic-gate 1076*7c478bd9Sstevel@tonic-gate if (SP->imode && !SP->phys_irm) 1077*7c478bd9Sstevel@tonic-gate _ONINSERT(); 1078*7c478bd9Sstevel@tonic-gate /* width of the old character that was overwritten */ 1079*7c478bd9Sstevel@tonic-gate w = _curs_scrwidth[TYPE(RBYTE(curscr->_y[cy][x]))]; 1080*7c478bd9Sstevel@tonic-gate 1081*7c478bd9Sstevel@tonic-gate if (insert_character) 1082*7c478bd9Sstevel@tonic-gate for (ix = 0; ix < w; ++ix) 1083*7c478bd9Sstevel@tonic-gate _PUTS(insert_character, 1); 1084*7c478bd9Sstevel@tonic-gate else 1085*7c478bd9Sstevel@tonic-gate if (parm_ich && !SP->imode) 1086*7c478bd9Sstevel@tonic-gate _PUTS(tparm_p1(parm_ich, w), 1); 1087*7c478bd9Sstevel@tonic-gate 1088*7c478bd9Sstevel@tonic-gate if (_ATTR(sc) != curscr->_attrs) 1089*7c478bd9Sstevel@tonic-gate _VIDS(_ATTR(sc), curscr->_attrs); 1090*7c478bd9Sstevel@tonic-gate for (ix = x; w > 0; --w, ++ix) 1091*7c478bd9Sstevel@tonic-gate (void) _outwch(curscr->_y[cy][ix]); 1092*7c478bd9Sstevel@tonic-gate 1093*7c478bd9Sstevel@tonic-gate /* make sure the video attrs are ok */ 1094*7c478bd9Sstevel@tonic-gate if (marks && (_ATTR(sc) || _ATTR(wcp[wx]))) 1095*7c478bd9Sstevel@tonic-gate _VIDS(_ATTR(wcp[wx]), ~_ATTR(sc)); 1096*7c478bd9Sstevel@tonic-gate 1097*7c478bd9Sstevel@tonic-gate /* update screen image */ 1098*7c478bd9Sstevel@tonic-gate /* LINTED */ 1099*7c478bd9Sstevel@tonic-gate cx = (short) wx; 1100*7c478bd9Sstevel@tonic-gate curscr->_y[cy][wx] = wcp[wx]; 1101*7c478bd9Sstevel@tonic-gate for (x = wx + 1; x < scrco; ++x) { 1102*7c478bd9Sstevel@tonic-gate (void) _outwch(wcp[x]); 1103*7c478bd9Sstevel@tonic-gate curscr->_y[cy][x] = wcp[x]; 1104*7c478bd9Sstevel@tonic-gate } 1105*7c478bd9Sstevel@tonic-gate return; 1106*7c478bd9Sstevel@tonic-gate } 1107*7c478bd9Sstevel@tonic-gate 1108*7c478bd9Sstevel@tonic-gate /* put char out and update screen image */ 1109*7c478bd9Sstevel@tonic-gate (void) _outwch(tilde_glitch && _CHAR(wcp[wx]) == '~' ? '`' : wcp[wx]); 1110*7c478bd9Sstevel@tonic-gate 1111*7c478bd9Sstevel@tonic-gate 1112*7c478bd9Sstevel@tonic-gate 1113*7c478bd9Sstevel@tonic-gate 1114*7c478bd9Sstevel@tonic-gate 1115*7c478bd9Sstevel@tonic-gate 1116*7c478bd9Sstevel@tonic-gate 1117*7c478bd9Sstevel@tonic-gate 1118*7c478bd9Sstevel@tonic-gate curscr->_y[cy][wx] = wcp[wx]; 1119*7c478bd9Sstevel@tonic-gate 1120*7c478bd9Sstevel@tonic-gate for (x = wx + 1; x < scrco; ++x) { 1121*7c478bd9Sstevel@tonic-gate (void) _outwch(wcp[x]); 1122*7c478bd9Sstevel@tonic-gate curscr->_y[cy][x] = wcp[x]; 1123*7c478bd9Sstevel@tonic-gate } 1124*7c478bd9Sstevel@tonic-gate 1125*7c478bd9Sstevel@tonic-gate /* make sure that wrap-around happens */ 1126*7c478bd9Sstevel@tonic-gate if (!auto_right_margin || eat_newline_glitch) { 1127*7c478bd9Sstevel@tonic-gate (void) _outch('\r'); 1128*7c478bd9Sstevel@tonic-gate (void) _outch('\n'); 1129*7c478bd9Sstevel@tonic-gate } 1130*7c478bd9Sstevel@tonic-gate cx = 0; 1131*7c478bd9Sstevel@tonic-gate ++cy; 1132*7c478bd9Sstevel@tonic-gate } 1133*7c478bd9Sstevel@tonic-gate 1134*7c478bd9Sstevel@tonic-gate /* 1135*7c478bd9Sstevel@tonic-gate * Find the top-most line to do clear-to-eod. 1136*7c478bd9Sstevel@tonic-gate * 1137*7c478bd9Sstevel@tonic-gate * topy, boty: the region to consider 1138*7c478bd9Sstevel@tonic-gate */ 1139*7c478bd9Sstevel@tonic-gate 1140*7c478bd9Sstevel@tonic-gate static int 1141*7c478bd9Sstevel@tonic-gate _getceod(int topy, int boty) 1142*7c478bd9Sstevel@tonic-gate { 1143*7c478bd9Sstevel@tonic-gate chtype *wcp, *ecp; 1144*7c478bd9Sstevel@tonic-gate int wy; 1145*7c478bd9Sstevel@tonic-gate short *begch, *endch, *begns; 1146*7c478bd9Sstevel@tonic-gate 1147*7c478bd9Sstevel@tonic-gate /* do nothing */ 1148*7c478bd9Sstevel@tonic-gate if ((topy + 1) >= boty) 1149*7c478bd9Sstevel@tonic-gate return (boty); 1150*7c478bd9Sstevel@tonic-gate 1151*7c478bd9Sstevel@tonic-gate wy = boty - 1; 1152*7c478bd9Sstevel@tonic-gate begch = _virtscr->_firstch + wy; 1153*7c478bd9Sstevel@tonic-gate endch = _virtscr->_lastch + wy; 1154*7c478bd9Sstevel@tonic-gate begns = _BEGNS + wy; 1155*7c478bd9Sstevel@tonic-gate 1156*7c478bd9Sstevel@tonic-gate for (; wy >= topy; --wy, --begch, --endch, --begns) { 1157*7c478bd9Sstevel@tonic-gate if (*endch == _BLANK || (*begch >= scrco && *begns >= scrco)) 1158*7c478bd9Sstevel@tonic-gate continue; 1159*7c478bd9Sstevel@tonic-gate 1160*7c478bd9Sstevel@tonic-gate wcp = _virtscr->_y[wy]; 1161*7c478bd9Sstevel@tonic-gate ecp = wcp + scrco; 1162*7c478bd9Sstevel@tonic-gate for (; wcp < ecp; ++wcp) 1163*7c478bd9Sstevel@tonic-gate if (_DARKCHAR(*wcp)) 1164*7c478bd9Sstevel@tonic-gate break; 1165*7c478bd9Sstevel@tonic-gate if (wcp != ecp) 1166*7c478bd9Sstevel@tonic-gate break; 1167*7c478bd9Sstevel@tonic-gate 1168*7c478bd9Sstevel@tonic-gate *endch = _BLANK; 1169*7c478bd9Sstevel@tonic-gate } 1170*7c478bd9Sstevel@tonic-gate 1171*7c478bd9Sstevel@tonic-gate return (wy + 1); 1172*7c478bd9Sstevel@tonic-gate } 1173*7c478bd9Sstevel@tonic-gate 1174*7c478bd9Sstevel@tonic-gate /* Use hardware clear-to-bottom. */ 1175*7c478bd9Sstevel@tonic-gate 1176*7c478bd9Sstevel@tonic-gate static void 1177*7c478bd9Sstevel@tonic-gate _useceod(int topy, int boty) 1178*7c478bd9Sstevel@tonic-gate { 1179*7c478bd9Sstevel@tonic-gate short *begns, *begch; 1180*7c478bd9Sstevel@tonic-gate 1181*7c478bd9Sstevel@tonic-gate /* skip lines already blanked */ 1182*7c478bd9Sstevel@tonic-gate begch = _virtscr->_firstch + topy; 1183*7c478bd9Sstevel@tonic-gate begns = _BEGNS + topy; 1184*7c478bd9Sstevel@tonic-gate for (; topy < boty; ++topy, ++begns, ++begch) 1185*7c478bd9Sstevel@tonic-gate if (*begns < scrco || *begch == _REDRAW) 1186*7c478bd9Sstevel@tonic-gate break; 1187*7c478bd9Sstevel@tonic-gate else 1188*7c478bd9Sstevel@tonic-gate *begch = _INFINITY; 1189*7c478bd9Sstevel@tonic-gate 1190*7c478bd9Sstevel@tonic-gate /* nothing to do */ 1191*7c478bd9Sstevel@tonic-gate if (topy + 1 >= boty) 1192*7c478bd9Sstevel@tonic-gate return; 1193*7c478bd9Sstevel@tonic-gate 1194*7c478bd9Sstevel@tonic-gate /* see if bottom is clear */ 1195*7c478bd9Sstevel@tonic-gate for (begns = _BEGNS + boty; boty < scrli; ++boty, ++begns) 1196*7c478bd9Sstevel@tonic-gate if (*begns < scrco) 1197*7c478bd9Sstevel@tonic-gate return; 1198*7c478bd9Sstevel@tonic-gate 1199*7c478bd9Sstevel@tonic-gate /* use clear-screen if appropriate */ 1200*7c478bd9Sstevel@tonic-gate if (topy == 0) { 1201*7c478bd9Sstevel@tonic-gate /* SS: colors */ 1202*7c478bd9Sstevel@tonic-gate if (back_color_erase) 1203*7c478bd9Sstevel@tonic-gate _turn_off_background(); 1204*7c478bd9Sstevel@tonic-gate 1205*7c478bd9Sstevel@tonic-gate _PUTS(clear_screen, scrli); 1206*7c478bd9Sstevel@tonic-gate cy = 0; cx = 0; 1207*7c478bd9Sstevel@tonic-gate (void) werase(curscr); 1208*7c478bd9Sstevel@tonic-gate } else 1209*7c478bd9Sstevel@tonic-gate 1210*7c478bd9Sstevel@tonic-gate /* use clear-to-end-of-display or delete lines */ 1211*7c478bd9Sstevel@tonic-gate if (clr_eos || (parm_delete_line && !memory_below)) { 1212*7c478bd9Sstevel@tonic-gate (void) mvcur(cy, cx, topy, 0); 1213*7c478bd9Sstevel@tonic-gate /* LINTED */ 1214*7c478bd9Sstevel@tonic-gate cy = (short) topy; 1215*7c478bd9Sstevel@tonic-gate cx = 0; 1216*7c478bd9Sstevel@tonic-gate /* SS: colors */ 1217*7c478bd9Sstevel@tonic-gate if (back_color_erase) 1218*7c478bd9Sstevel@tonic-gate _turn_off_background(); 1219*7c478bd9Sstevel@tonic-gate _PUTS(clr_eos ? clr_eos : tparm_p1(parm_delete_line, 1220*7c478bd9Sstevel@tonic-gate scrli - topy), scrli - topy); 1221*7c478bd9Sstevel@tonic-gate 1222*7c478bd9Sstevel@tonic-gate /* update curscr */ 1223*7c478bd9Sstevel@tonic-gate /* LINTED */ 1224*7c478bd9Sstevel@tonic-gate curscr->_cury = (short) topy; 1225*7c478bd9Sstevel@tonic-gate curscr->_curx = 0; 1226*7c478bd9Sstevel@tonic-gate (void) wclrtobot(curscr); 1227*7c478bd9Sstevel@tonic-gate } else 1228*7c478bd9Sstevel@tonic-gate /* no hardware support */ 1229*7c478bd9Sstevel@tonic-gate return; 1230*7c478bd9Sstevel@tonic-gate 1231*7c478bd9Sstevel@tonic-gate /* correct the update structure */ 1232*7c478bd9Sstevel@tonic-gate (void) wtouchln(_virtscr, topy, scrli, FALSE); 1233*7c478bd9Sstevel@tonic-gate } 1234*7c478bd9Sstevel@tonic-gate 1235*7c478bd9Sstevel@tonic-gate 1236*7c478bd9Sstevel@tonic-gate static void 1237*7c478bd9Sstevel@tonic-gate _turn_off_background(void) 1238*7c478bd9Sstevel@tonic-gate { 1239*7c478bd9Sstevel@tonic-gate /* this routine turn the background color to zero. This need to be */ 1240*7c478bd9Sstevel@tonic-gate /* done only in forllowing cases: */ 1241*7c478bd9Sstevel@tonic-gate /* 1) We are using Tek type terminal (which has bce terminfo */ 1242*7c478bd9Sstevel@tonic-gate /* variable) */ 1243*7c478bd9Sstevel@tonic-gate /* 2) The current background is not already zero */ 1244*7c478bd9Sstevel@tonic-gate 1245*7c478bd9Sstevel@tonic-gate if (set_background && cur_term->_cur_pair.background > 0) { 1246*7c478bd9Sstevel@tonic-gate _PUTS(orig_pair, 1); 1247*7c478bd9Sstevel@tonic-gate cur_term->_cur_pair.foreground = -1; 1248*7c478bd9Sstevel@tonic-gate cur_term->_cur_pair.background = -1; 1249*7c478bd9Sstevel@tonic-gate curscr->_attrs &= ~A_COLOR; 1250*7c478bd9Sstevel@tonic-gate } 1251*7c478bd9Sstevel@tonic-gate } 1252