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