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