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 (c) 1995-1998 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 /* LINTLIBRARY */ 28 29 /* 30 * wrefresh.c 31 * 32 * XCurses Library 33 * 34 * Copyright 1990, 1995 by Mortice Kern Systems Inc. All rights reserved. 35 * 36 */ 37 38 #ifdef M_RCSID 39 #ifndef lint 40 static char rcsID[] = 41 "$Header: /team/ps/sun_xcurses/archive/local_changes/xcurses/src/lib/" 42 "libxcurses/src/libc/xcurses/rcs/wrefresh.c 1.7 1998/06/04 17:52:06 " 43 "cbates Exp $"; 44 #endif 45 #endif 46 47 #include <private.h> 48 #include <string.h> 49 50 /* 51 * Update curscr with the given window then display to the terminal. 52 * Unless leaveok() has been enabled, the physical cursor of the 53 * terminal is left at the location of the cursor for that window. 54 */ 55 int 56 wrefresh(WINDOW *w) 57 { 58 int value; 59 60 if (w == curscr) 61 value = clearok(__m_screen->_newscr, TRUE); 62 else 63 value = wnoutrefresh(w); 64 65 if (value == OK) 66 value = doupdate(); 67 68 return (value); 69 } 70 71 /* 72 * Update newscr with the given window. This allows newscr to be 73 * updated with several windows before doing a doupdate() (and so 74 * improve the efficiency of multiple updates in comparison to 75 * looping through wrefresh() for all windows). 76 */ 77 int 78 wnoutrefresh(WINDOW *w) 79 { 80 int wy, wx, ny, nx, dx, value; 81 WINDOW *ns = __m_screen->_newscr; 82 83 /* Kluge to make test suite happy ... */ 84 if (w == stdscr) 85 (void) slk_noutrefresh(); 86 87 value = (w->_flags & W_IS_PAD) ? ERR : OK; 88 89 if (value == OK) { 90 /* 91 * This loop is similar to what copywin() does, except that 92 * this loop only copies dirty lines, while copywin() copies 93 * every line. 94 */ 95 for (wy = 0, ny = w->_begy; wy < w->_maxy; ++wy, ++ny) { 96 /* Has line been touched? */ 97 if (w->_last[wy] <= w->_first[wy]) 98 continue; 99 100 wx = w->_first[wy]; 101 nx = w->_begx + wx; 102 dx = w->_last[wy] - wx; 103 104 /* 105 * Case 3 - Check target window for overlap of broad 106 * characters around the outer edge of the source 107 * window's location. 108 */ 109 (void) memcpy(&ns->_line[ny][nx], &w->_line[wy][wx], 110 dx * sizeof (**w->_line)); 111 112 /* Make destination dirtier */ 113 if (ns->_first[ny] > nx) 114 ns->_first[ny] = (short) nx; 115 116 if (ns->_last[ny] < (nx + dx)) 117 ns->_last[ny] = (short) (nx + dx); 118 119 if (!ns->_line[ny][nx]._f) { 120 /* 121 * Case 5 - Incomplete glyph copied from 122 * source at screen margins. 123 */ 124 if (nx <= 0) 125 (void) __m_cc_erase(ns, ny, 0, ny, 0); 126 #ifdef M_CURSES_SENSIBLE_WINDOWS 127 /* 128 * Case 4 - Expand incomplete glyph from 129 * source into target window. 130 */ 131 else if (0 < nx) 132 (void) __m_cc_expand(ns, ny, nx, -1); 133 #endif /* M_CURSES_SENSIBLE_WINDOWS */ 134 } 135 136 if (!__m_cc_islast(ns, ny, nx+dx-1)) { 137 /* 138 * Case 5 - Incomplete glyph copied from 139 * source at screen margins. 140 */ 141 if (ns->_maxx <= nx + dx) 142 (void) __m_cc_erase(ns, ny, nx + dx - 1, 143 ny, nx + dx - 1); 144 #ifdef M_CURSES_SENSIBLE_WINDOWS 145 /* 146 * Case 4 - Expand incomplete glyph from 147 * source into target window. 148 */ 149 else if (nx + dx < ns->_maxx) 150 (void) __m_cc_expand(ns, ny, 151 nx + dx - 1, 1); 152 #endif /* M_CURSES_SENSIBLE_WINDOWS */ 153 } 154 155 /* Untouch line. */ 156 w->_first[wy] = w->_maxx; 157 w->_last[wy] = -1; 158 159 /* Remember refresh region (inclusive). */ 160 w->_refy = w->_begy; 161 w->_refx = w->_begx; 162 w->_sminy = w->_sminx = 0; 163 w->_smaxy = ns->_maxy - 1; 164 w->_smaxx = ns->_maxx - 1; 165 } 166 167 ns->_scroll = w->_scroll; 168 w->_scroll = 0; 169 170 /* Last refreshed window controls W_LEAVE_CURSOR flag. */ 171 ns->_flags &= ~W_LEAVE_CURSOR; 172 ns->_cury = w->_cury + w->_begy; 173 ns->_curx = w->_curx + w->_begx; 174 175 ns->_flags |= w->_flags & 176 (W_CLEAR_WINDOW | W_REDRAW_WINDOW | W_LEAVE_CURSOR); 177 w->_flags &= ~(W_CLEAR_WINDOW | W_REDRAW_WINDOW); 178 } 179 180 return (value); 181 } 182 183 /* 184 * Check overlaping region on a line. 185 * 186 * When copying a source window region over another target window 187 * region, we have a few cases which to concern ourselves with. 188 * 189 * Let {, [, ( and ), ], } denote the left and right halves of 190 * broad glyphes. 191 * 192 * Let alpha-numerics and periods (.) be narrow glyphes. 193 * 194 * Let hash (#) be a narrow background character. 195 * 196 * Let vertical bar, hyphen, and plus represent the borders 197 * of a window. 198 * 199 * 1. Copy narrow characters over narrow characters. 200 * copywin(s, t, 0, 1, 0, 1, 1, 3, 0) 201 * s t ==> t 202 * +------+ +------+ +------+ 203 * |abcdef| |......| |.bcd..| 204 * |ghijkl| |......| |.hij..| 205 * |mnopqr| |......| |......| 206 * +------+ +------+ +------+ 207 * Nothing special. 208 * 209 * 2. Copy whole broad characters over narrow characters. 210 * copywin(s, t, 0, 1, 0, 1, 1, 3, 0) 211 * s t ==> t 212 * +------+ +------+ +------+ 213 * |a[]def| |......| |.[]d..| 214 * |gh{}kl| |......| |.h{}..| 215 * |mnopqr| |......| |......| 216 * +------+ +------+ +------+ 217 * Nothing special. 218 * 219 * 3. Copy narrow from source overlaps broad in target. 220 * copywin(s, t, 0, 1, 0, 1, 1, 3, 0) 221 * s t ==> t 222 * +------+ +------+ +------+ 223 * |abcdef| |[]....| |#bcd..| 224 * |ghijkl| |...{}.| |.hij#.| 225 * |mnopqr| |......| |......| 226 * +------+ +------+ +------+ 227 * The # background characters have wiped out the remaining 228 * halves of broad characters. This may result also with 229 * a wnoutrefresh() of a window onto curscr. 230 * 231 * The following case appears to be disallowed in XPG4 V2 232 * and I think they're wrong, so I've conditionalised the code 233 * on M_CURSES_SENSIBLE_WINDOWS. 234 * 235 * 4. Copy incomplete broad from source to target. 236 * copywin(s, t, 0, 1, 0, 1, 1, 3, 0) 237 * s t ==> t 238 * +------+ +------+ +------+ 239 * |[]cdef| |123456| |[]cd56| 240 * |ghi{}l| |789012| |7hi{}2| 241 * |mnopqr| |......| |......| 242 * +------+ +------+ +------+ 243 * The ] and { halves of broad characters have been copied and 244 * expanded into the target outside of the specified target region. 245 * This may result also with a wnoutrefresh() of a window onto 246 * curscr. 247 * 248 * Consider a pop-up dialog that contains narrow characters and 249 * a base window that contains broad characters and we do the 250 * following: 251 * 252 * save = dupwin(dialog); // create backing store 253 * overwrite(curscr, save); // save region to be overlayed 254 * wrefresh(dialog); // display dialog 255 * ... // do dialog stuff 256 * wrefresh(save); // restore screen image 257 * delwin(save); // release backing store 258 * 259 * Code similar to this has been used to implement generic popup() 260 * and popdown() routines. In the simple case where the base window 261 * contains narrow characters only, it would be correctly restored. 262 * 263 * However with broad characters, the overwrite() could copy a 264 * region with incomplete broad characters. The wrefresh(dialog) 265 * results in case 3. In order to restore the window correctly with 266 * wrefresh(save), we require case 4. 267 * 268 * 5. Copy incomplete broad from source to target region next to margin. 269 * 270 * a) 271 * copywin(s, t, 0, 1, 0, 0, 1, 2, 0) 272 * s t ==> t 273 * +------+ +------+ +------+ 274 * |[]cdef| |123456| |#cd456| 275 * |ghijkl| |789012| |hij012| 276 * |mnopqr| |......| |......| 277 * +------+ +------+ +------+ 278 * The # background character has replaced the ] character that 279 * would have been copied from the source, because it is not possible 280 * to expand the broad character to its complete form (case 4). 281 * 282 * b) 283 * copywin(s, t, 0, 1, 0, 3, 1, 5, 0) 284 * s t ==> t 285 * +------+ +------+ +------+ 286 * |abcdef| |123456| |123bcd| 287 * |ghi{}l| |789012| |789hi#| 288 * |mnopqr| |......| |......| 289 * +------+ +------+ +------+ 290 * Same a 5a. but with the right margin. 291 */ 292