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