1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1997 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1988 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * University Copyright- Copyright (c) 1982, 1986, 1988 32 * The Regents of the University of California 33 * All Rights Reserved 34 * 35 * University Acknowledgment- Portions of this document are derived from 36 * software developed by the University of California, Berkeley, and its 37 * contributors. 38 */ 39 40 #pragma ident "%Z%%M% %I% %E% SMI" 41 42 /*LINTLIBRARY*/ 43 44 #include <sys/types.h> 45 #include <string.h> 46 #include "curses_inc.h" 47 48 /* 49 * Insert/delete lines 50 * id < 0 : number of lines to delete 51 * id > 0 : number of lines to insert 52 */ 53 54 int 55 winsdelln(WINDOW *win, int id) 56 { 57 int endy, endx, to, fr, num_lines, dir; 58 chtype *sw; 59 char *mk; 60 bool savimmed, savesync; 61 short x, y, quick, *begch, *endch; 62 #ifdef _VR3_COMPAT_CODE 63 /* LINTED */ 64 void (*update_ptr)(); 65 66 /* 67 * Null out the update pointer so that in wclrtoeol we do not 68 * update the _y16 area but we wait till the bottom of this 69 * function to do it in one fell swoop. 70 */ 71 72 if (_y16update) { 73 update_ptr = _y16update; 74 _y16update = NULL; 75 } else 76 update_ptr = NULL; 77 #endif /* _VR3_COMPAT_CODE */ 78 79 if ((win->_cury >= win->_tmarg) && (win->_cury <= win->_bmarg)) 80 endy = win->_bmarg + 1; 81 else 82 endy = win->_maxy; 83 84 if (id < 0) { 85 /* 86 * Check that the amount of lines to delete aren't larger 87 * than the window. We save num_lines only so that we 88 * don't have to re-compute if the if comes out true. 89 */ 90 91 if ((num_lines = win->_cury - endy) > id) 92 id = num_lines; 93 94 /* 95 * "fr" is the line that we are coming "fr"om and 96 * moving "to" the new place. This is the offset which 97 * we have to re-align our pointers by. 98 * We want to start setting the current line's pointer 99 * to point to the offset's line. We want to move line "fr" 100 * to line "to". 101 */ 102 103 to = win->_cury; 104 fr = to - id; 105 num_lines = endy - fr; 106 dir = 1; 107 } else { 108 /* can't insert more lines than are in the region */ 109 if ((num_lines = endy - win->_cury) < id) 110 id = num_lines; 111 112 to = endy - 1; 113 fr = to - id; 114 num_lines = fr - (win->_cury - 1); 115 dir = -1; 116 } 117 118 /* 119 * If this window has no parents or children, then we can manipulate 120 * pointers to simulate insert/delete line. Otherwise, 121 * to propogate the changes to parents and siblings 122 * we have to memcpy the text around. 123 * 124 * Set quick to tell us which we have to do. 125 */ 126 quick = ((win->_ndescs <= 0) && (win->_parent == NULL)); 127 128 begch = win->_firstch; 129 endch = win->_lastch; 130 endx = win->_maxx; 131 132 for (; num_lines > 0; num_lines--, to += dir, fr += dir) { 133 /* can be done quickly */ 134 if (quick) { 135 sw = win->_y[to]; 136 win->_y[to] = win->_y[fr]; 137 win->_y[fr] = sw; 138 if ((win == curscr) && _MARKS != NULL) { 139 mk = _MARKS[to]; 140 _MARKS[to] = _MARKS[fr]; 141 _MARKS[fr] = mk; 142 143 /* for color terminal do the same for */ 144 /* color marks */ 145 146 if (_COLOR_MARKS != NULL) { 147 mk = _COLOR_MARKS[to]; 148 _COLOR_MARKS[to] = _COLOR_MARKS[fr]; 149 _COLOR_MARKS[fr] = mk; 150 } 151 } 152 } else 153 /* slow update */ 154 (void) memcpy((char *) win->_y[to], (char *) 155 win->_y[fr], (endx * sizeof (chtype))); 156 157 158 /* 159 * If this is curscr, the firstch[] and lastch[] 160 * arrays contain blank information. 161 */ 162 163 if (win == curscr) { 164 begch[to] = begch[fr]; 165 endch[to] = endch[fr]; 166 _CURHASH[to] = _CURHASH[fr]; 167 } else { 168 /* regular window, update the change structure */ 169 begch[to] = 0; 170 endch[to] = endx - 1; 171 } 172 } 173 174 /* clear the insert/delete lines */ 175 if (id < 0) 176 num_lines = endy - to; 177 else 178 num_lines = to - (win->_cury - 1); 179 180 if (num_lines > 0) { /* Is this if needed ? */ 181 savimmed = win->_immed; 182 savesync = win->_sync; 183 win->_immed = win->_sync = FALSE; 184 x = win->_curx; 185 y = win->_cury; 186 187 win->_curx = 0; 188 for (; num_lines > 0; --num_lines, to += dir) { 189 /* LINTED */ 190 win->_cury = (short) to; 191 (void) wclrtoeol(win); 192 } 193 194 win->_curx = x; 195 win->_cury = y; 196 win->_immed = savimmed; 197 win->_sync = savesync; 198 } 199 win->_flags |= (_WINCHANGED|_WINSDEL); 200 201 #ifdef _VR3_COMPAT_CODE 202 if (update_ptr) { 203 _y16update = update_ptr; 204 (*_y16update)(win, endy - y, endx, y, 0); 205 } 206 #endif /* _VR3_COMPAT_CODE */ 207 208 if (win->_sync) 209 wsyncup(win); 210 211 return ((win != curscr && savimmed) ? wrefresh(win) : OK); 212 } 213