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
wrefresh(w)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
wnoutrefresh(w)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