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