17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate * with the License.
87c478bd9Sstevel@tonic-gate *
97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate * and limitations under the License.
137c478bd9Sstevel@tonic-gate *
147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate *
207c478bd9Sstevel@tonic-gate * CDDL HEADER END
217c478bd9Sstevel@tonic-gate */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate * Copyright (c) 1995, by Sun Microsystems, Inc.
247c478bd9Sstevel@tonic-gate * All rights reserved.
257c478bd9Sstevel@tonic-gate */
267c478bd9Sstevel@tonic-gate
277c478bd9Sstevel@tonic-gate /*
287c478bd9Sstevel@tonic-gate * wrefresh.c
297c478bd9Sstevel@tonic-gate *
307c478bd9Sstevel@tonic-gate * XCurses Library
317c478bd9Sstevel@tonic-gate *
327c478bd9Sstevel@tonic-gate * Copyright 1990, 1995 by Mortice Kern Systems Inc. All rights reserved.
337c478bd9Sstevel@tonic-gate *
347c478bd9Sstevel@tonic-gate */
357c478bd9Sstevel@tonic-gate
367c478bd9Sstevel@tonic-gate #ifdef M_RCSID
377c478bd9Sstevel@tonic-gate #ifndef lint
387c478bd9Sstevel@tonic-gate static char rcsID[] = "$Header: /rd/src/libc/xcurses/rcs/wrefresh.c 1.3 1995/06/20 14:34:14 ant Exp $";
397c478bd9Sstevel@tonic-gate #endif
407c478bd9Sstevel@tonic-gate #endif
417c478bd9Sstevel@tonic-gate
427c478bd9Sstevel@tonic-gate #include <private.h>
437c478bd9Sstevel@tonic-gate #include <string.h>
447c478bd9Sstevel@tonic-gate
457c478bd9Sstevel@tonic-gate /*f
46*1da57d55SToomas Soome * Update curscr with the given window then display to the terminal.
47*1da57d55SToomas Soome * Unless leaveok() has been enabled, the physical cursor of the
487c478bd9Sstevel@tonic-gate * terminal is left at the location of the cursor for that window.
497c478bd9Sstevel@tonic-gate */
507c478bd9Sstevel@tonic-gate int
wrefresh(w)517c478bd9Sstevel@tonic-gate wrefresh(w)
527c478bd9Sstevel@tonic-gate WINDOW *w;
537c478bd9Sstevel@tonic-gate {
547c478bd9Sstevel@tonic-gate int value;
557c478bd9Sstevel@tonic-gate
567c478bd9Sstevel@tonic-gate #ifdef M_CURSES_TRACE
577c478bd9Sstevel@tonic-gate __m_trace("wrefresh(%p)", w);
587c478bd9Sstevel@tonic-gate #endif
597c478bd9Sstevel@tonic-gate if (w == curscr)
607c478bd9Sstevel@tonic-gate value = clearok(__m_screen->_newscr, TRUE);
617c478bd9Sstevel@tonic-gate else
627c478bd9Sstevel@tonic-gate value = wnoutrefresh(w);
637c478bd9Sstevel@tonic-gate
647c478bd9Sstevel@tonic-gate if (value == OK)
657c478bd9Sstevel@tonic-gate value = doupdate();
667c478bd9Sstevel@tonic-gate
677c478bd9Sstevel@tonic-gate return __m_return_code("wrefresh", value);
687c478bd9Sstevel@tonic-gate }
697c478bd9Sstevel@tonic-gate
707c478bd9Sstevel@tonic-gate /*f
71*1da57d55SToomas Soome * Update newscr with the given window. This allows newscr to be
72*1da57d55SToomas Soome * updated with several windows before doing a doupdate() (and so
73*1da57d55SToomas Soome * improve the efficiency of multiple updates in comparison to
747c478bd9Sstevel@tonic-gate * looping through wrefresh() for all windows).
757c478bd9Sstevel@tonic-gate */
767c478bd9Sstevel@tonic-gate int
wnoutrefresh(w)777c478bd9Sstevel@tonic-gate wnoutrefresh(w)
787c478bd9Sstevel@tonic-gate WINDOW *w;
797c478bd9Sstevel@tonic-gate {
807c478bd9Sstevel@tonic-gate int wy, wx, ny, nx, dx, value;
817c478bd9Sstevel@tonic-gate WINDOW *ns = __m_screen->_newscr;
827c478bd9Sstevel@tonic-gate
837c478bd9Sstevel@tonic-gate #ifdef M_CURSES_TRACE
847c478bd9Sstevel@tonic-gate __m_trace("wnoutrefresh(%p)", w);
857c478bd9Sstevel@tonic-gate #endif
867c478bd9Sstevel@tonic-gate
877c478bd9Sstevel@tonic-gate value = (w->_flags & W_IS_PAD) ? ERR : OK;
887c478bd9Sstevel@tonic-gate
897c478bd9Sstevel@tonic-gate if (value == OK) {
907c478bd9Sstevel@tonic-gate /* This loop is similar to what copywin() does, except that
917c478bd9Sstevel@tonic-gate * this loop only copies dirty lines, while copywin() copies
927c478bd9Sstevel@tonic-gate * every line.
937c478bd9Sstevel@tonic-gate */
947c478bd9Sstevel@tonic-gate for (wy = 0, ny = w->_begy; wy < w->_maxy; ++wy, ++ny) {
957c478bd9Sstevel@tonic-gate /* Has line been touched? */
967c478bd9Sstevel@tonic-gate if (w->_last[wy] <= w->_first[wy])
977c478bd9Sstevel@tonic-gate continue;
987c478bd9Sstevel@tonic-gate
997c478bd9Sstevel@tonic-gate wx = w->_first[wy];
1007c478bd9Sstevel@tonic-gate nx = w->_begx + wx;
1017c478bd9Sstevel@tonic-gate dx = w->_last[wy] - wx;
1027c478bd9Sstevel@tonic-gate
1037c478bd9Sstevel@tonic-gate /* Case 3 - Check target window for overlap of broad
1047c478bd9Sstevel@tonic-gate * characters around the outer edge of the source
105*1da57d55SToomas Soome * window's location.
1067c478bd9Sstevel@tonic-gate */
1077c478bd9Sstevel@tonic-gate (void) __m_cc_erase(ns, ny, nx, ny, nx);
1087c478bd9Sstevel@tonic-gate (void) __m_cc_erase(ns, ny, nx+dx-1, ny, nx+dx-1);
1097c478bd9Sstevel@tonic-gate
1107c478bd9Sstevel@tonic-gate (void) memcpy(
1117c478bd9Sstevel@tonic-gate &ns->_line[ny][nx], &w->_line[wy][wx],
1127c478bd9Sstevel@tonic-gate dx * sizeof **w->_line
1137c478bd9Sstevel@tonic-gate );
1147c478bd9Sstevel@tonic-gate
1157c478bd9Sstevel@tonic-gate if (!ns->_line[ny][nx]._f) {
116*1da57d55SToomas Soome /* Case 5 - Incomplete glyph copied from
1177c478bd9Sstevel@tonic-gate * source at screen margins.
1187c478bd9Sstevel@tonic-gate */
1197c478bd9Sstevel@tonic-gate if (nx <= 0)
1207c478bd9Sstevel@tonic-gate (void) __m_cc_erase(ns, ny, 0, ny, 0);
1217c478bd9Sstevel@tonic-gate #ifdef M_CURSES_SENSIBLE_WINDOWS
122*1da57d55SToomas Soome /* Case 4 - Expand incomplete glyph from
1237c478bd9Sstevel@tonic-gate * source into target window.
1247c478bd9Sstevel@tonic-gate */
1257c478bd9Sstevel@tonic-gate else if (0 < nx)
1267c478bd9Sstevel@tonic-gate (void) __m_cc_expand(ns, ny, nx, -1);
1277c478bd9Sstevel@tonic-gate #endif /* M_CURSES_SENSIBLE_WINDOWS */
1287c478bd9Sstevel@tonic-gate }
1297c478bd9Sstevel@tonic-gate
1307c478bd9Sstevel@tonic-gate if (!__m_cc_islast(ns, ny, nx+dx-1)) {
131*1da57d55SToomas Soome /* Case 5 - Incomplete glyph copied from
1327c478bd9Sstevel@tonic-gate * source at screen margins.
1337c478bd9Sstevel@tonic-gate */
1347c478bd9Sstevel@tonic-gate if (ns->_maxx <= nx + dx)
1357c478bd9Sstevel@tonic-gate (void) __m_cc_erase(
1367c478bd9Sstevel@tonic-gate ns, ny, nx+dx-1, ny, nx+dx-1
1377c478bd9Sstevel@tonic-gate );
1387c478bd9Sstevel@tonic-gate #ifdef M_CURSES_SENSIBLE_WINDOWS
139*1da57d55SToomas Soome /* Case 4 - Expand incomplete glyph from
1407c478bd9Sstevel@tonic-gate * source into target window.
1417c478bd9Sstevel@tonic-gate */
1427c478bd9Sstevel@tonic-gate else if (nx + dx < ns->_maxx)
1437c478bd9Sstevel@tonic-gate (void) __m_cc_expand(
1447c478bd9Sstevel@tonic-gate ns, ny, nx+dx-1, 1
1457c478bd9Sstevel@tonic-gate );
1467c478bd9Sstevel@tonic-gate #endif /* M_CURSES_SENSIBLE_WINDOWS */
1477c478bd9Sstevel@tonic-gate }
148*1da57d55SToomas Soome
1497c478bd9Sstevel@tonic-gate /* Untouch line. */
1507c478bd9Sstevel@tonic-gate w->_first[wy] = w->_maxx;
1517c478bd9Sstevel@tonic-gate w->_last[wy] = -1;
1527c478bd9Sstevel@tonic-gate
1537c478bd9Sstevel@tonic-gate /* Remember refresh region (inclusive). */
1547c478bd9Sstevel@tonic-gate w->_refy = w->_begy;
1557c478bd9Sstevel@tonic-gate w->_refx = w->_begx;
1567c478bd9Sstevel@tonic-gate w->_sminy = w->_sminx = 0;
1577c478bd9Sstevel@tonic-gate w->_smaxy = ns->_maxy-1;
1587c478bd9Sstevel@tonic-gate w->_smaxx = ns->_maxx-1;
1597c478bd9Sstevel@tonic-gate }
1607c478bd9Sstevel@tonic-gate
1617c478bd9Sstevel@tonic-gate ns->_scroll = w->_scroll;
1627c478bd9Sstevel@tonic-gate w->_scroll = 0;
1637c478bd9Sstevel@tonic-gate
1647c478bd9Sstevel@tonic-gate /* Last refreshed window controls W_LEAVE_CURSOR flag. */
1657c478bd9Sstevel@tonic-gate ns->_flags &= ~W_LEAVE_CURSOR;
1667c478bd9Sstevel@tonic-gate ns->_cury = w->_cury + w->_begy;
1677c478bd9Sstevel@tonic-gate ns->_curx = w->_curx + w->_begx;
1687c478bd9Sstevel@tonic-gate
169*1da57d55SToomas Soome ns->_flags |= w->_flags
1707c478bd9Sstevel@tonic-gate & (W_CLEAR_WINDOW | W_REDRAW_WINDOW | W_LEAVE_CURSOR);
1717c478bd9Sstevel@tonic-gate w->_flags &= ~(W_CLEAR_WINDOW | W_REDRAW_WINDOW);
1727c478bd9Sstevel@tonic-gate }
1737c478bd9Sstevel@tonic-gate
1747c478bd9Sstevel@tonic-gate return __m_return_code("wnoutrefresh", value);
1757c478bd9Sstevel@tonic-gate }
1767c478bd9Sstevel@tonic-gate
1777c478bd9Sstevel@tonic-gate /*
1787c478bd9Sstevel@tonic-gate * Check overlaping region on a line.
1797c478bd9Sstevel@tonic-gate *
180*1da57d55SToomas Soome * When copying a source window region over another target window
1817c478bd9Sstevel@tonic-gate * region, we have a few cases which to concern ourselves with.
1827c478bd9Sstevel@tonic-gate *
1837c478bd9Sstevel@tonic-gate * Let {, [, ( and ), ], } denote the left and right halves of
1847c478bd9Sstevel@tonic-gate * broad glyphes.
1857c478bd9Sstevel@tonic-gate *
1867c478bd9Sstevel@tonic-gate * Let alpha-numerics and periods (.) be narrow glyphes.
1877c478bd9Sstevel@tonic-gate *
1887c478bd9Sstevel@tonic-gate * Let hash (#) be a narrow background character.
1897c478bd9Sstevel@tonic-gate *
190*1da57d55SToomas Soome * Let vertical bar, hyphen, and plus represent the borders
1917c478bd9Sstevel@tonic-gate * of a window.
1927c478bd9Sstevel@tonic-gate *
1937c478bd9Sstevel@tonic-gate * 1. Copy narrow characters over narrow characters.
1947c478bd9Sstevel@tonic-gate * copywin(s, t, 0, 1, 0, 1, 1, 3, 0)
195*1da57d55SToomas Soome * s t ==> t
1967c478bd9Sstevel@tonic-gate * +------+ +------+ +------+
1977c478bd9Sstevel@tonic-gate * |abcdef| |......| |.bcd..|
1987c478bd9Sstevel@tonic-gate * |ghijkl| |......| |.hij..|
1997c478bd9Sstevel@tonic-gate * |mnopqr| |......| |......|
2007c478bd9Sstevel@tonic-gate * +------+ +------+ +------+
2017c478bd9Sstevel@tonic-gate * Nothing special.
2027c478bd9Sstevel@tonic-gate *
2037c478bd9Sstevel@tonic-gate * 2. Copy whole broad characters over narrow characters.
2047c478bd9Sstevel@tonic-gate * copywin(s, t, 0, 1, 0, 1, 1, 3, 0)
205*1da57d55SToomas Soome * s t ==> t
2067c478bd9Sstevel@tonic-gate * +------+ +------+ +------+
2077c478bd9Sstevel@tonic-gate * |a[]def| |......| |.[]d..|
2087c478bd9Sstevel@tonic-gate * |gh{}kl| |......| |.h{}..|
2097c478bd9Sstevel@tonic-gate * |mnopqr| |......| |......|
2107c478bd9Sstevel@tonic-gate * +------+ +------+ +------+
2117c478bd9Sstevel@tonic-gate * Nothing special.
2127c478bd9Sstevel@tonic-gate *
2137c478bd9Sstevel@tonic-gate * 3. Copy narrow from source overlaps broad in target.
2147c478bd9Sstevel@tonic-gate * copywin(s, t, 0, 1, 0, 1, 1, 3, 0)
215*1da57d55SToomas Soome * s t ==> t
2167c478bd9Sstevel@tonic-gate * +------+ +------+ +------+
2177c478bd9Sstevel@tonic-gate * |abcdef| |[]....| |#bcd..|
2187c478bd9Sstevel@tonic-gate * |ghijkl| |...{}.| |.hij#.|
2197c478bd9Sstevel@tonic-gate * |mnopqr| |......| |......|
2207c478bd9Sstevel@tonic-gate * +------+ +------+ +------+
2217c478bd9Sstevel@tonic-gate * The # background characters have wiped out the remaining
2227c478bd9Sstevel@tonic-gate * halves of broad characters. This may result also with
2237c478bd9Sstevel@tonic-gate * a wnoutrefresh() of a window onto curscr.
2247c478bd9Sstevel@tonic-gate *
225*1da57d55SToomas Soome * The following case appears to be disallowed in XPG4 V2
226*1da57d55SToomas Soome * and I think they're wrong, so I've conditionalised the code
2277c478bd9Sstevel@tonic-gate * on M_CURSES_SENSIBLE_WINDOWS.
2287c478bd9Sstevel@tonic-gate *
2297c478bd9Sstevel@tonic-gate * 4. Copy incomplete broad from source to target.
2307c478bd9Sstevel@tonic-gate * copywin(s, t, 0, 1, 0, 1, 1, 3, 0)
231*1da57d55SToomas Soome * s t ==> t
2327c478bd9Sstevel@tonic-gate * +------+ +------+ +------+
2337c478bd9Sstevel@tonic-gate * |[]cdef| |123456| |[]cd56|
2347c478bd9Sstevel@tonic-gate * |ghi{}l| |789012| |7hi{}2|
2357c478bd9Sstevel@tonic-gate * |mnopqr| |......| |......|
2367c478bd9Sstevel@tonic-gate * +------+ +------+ +------+
2377c478bd9Sstevel@tonic-gate * The ] and { halves of broad characters have been copied and
2387c478bd9Sstevel@tonic-gate * expanded into the target outside of the specified target region.
2397c478bd9Sstevel@tonic-gate * This may result also with a wnoutrefresh() of a window onto
2407c478bd9Sstevel@tonic-gate * curscr.
2417c478bd9Sstevel@tonic-gate *
2427c478bd9Sstevel@tonic-gate * Consider a pop-up dialog that contains narrow characters and
2437c478bd9Sstevel@tonic-gate * a base window that contains broad characters and we do the
2447c478bd9Sstevel@tonic-gate * following:
245*1da57d55SToomas Soome *
2467c478bd9Sstevel@tonic-gate * save = dupwin(dialog); // create backing store
2477c478bd9Sstevel@tonic-gate * overwrite(curscr, save); // save region to be overlayed
2487c478bd9Sstevel@tonic-gate * wrefresh(dialog); // display dialog
2497c478bd9Sstevel@tonic-gate * ... // do dialog stuff
2507c478bd9Sstevel@tonic-gate * wrefresh(save); // restore screen image
2517c478bd9Sstevel@tonic-gate * delwin(save); // release backing store
2527c478bd9Sstevel@tonic-gate *
2537c478bd9Sstevel@tonic-gate * Code similar to this has been used to implement generic popup()
2547c478bd9Sstevel@tonic-gate * and popdown() routines. In the simple case where the base window
2557c478bd9Sstevel@tonic-gate * contains narrow characters only, it would be correctly restored.
2567c478bd9Sstevel@tonic-gate *
2577c478bd9Sstevel@tonic-gate * However with broad characters, the overwrite() could copy a
258*1da57d55SToomas Soome * region with incomplete broad characters. The wrefresh(dialog)
2597c478bd9Sstevel@tonic-gate * results in case 3. In order to restore the window correctly with
2607c478bd9Sstevel@tonic-gate * wrefresh(save), we require case 4.
2617c478bd9Sstevel@tonic-gate *
2627c478bd9Sstevel@tonic-gate * 5. Copy incomplete broad from source to target region next to margin.
2637c478bd9Sstevel@tonic-gate *
2647c478bd9Sstevel@tonic-gate * a)
2657c478bd9Sstevel@tonic-gate * copywin(s, t, 0, 1, 0, 0, 1, 2, 0)
266*1da57d55SToomas Soome * s t ==> t
2677c478bd9Sstevel@tonic-gate * +------+ +------+ +------+
2687c478bd9Sstevel@tonic-gate * |[]cdef| |123456| |#cd456|
2697c478bd9Sstevel@tonic-gate * |ghijkl| |789012| |hij012|
2707c478bd9Sstevel@tonic-gate * |mnopqr| |......| |......|
2717c478bd9Sstevel@tonic-gate * +------+ +------+ +------+
2727c478bd9Sstevel@tonic-gate * The # background character has replaced the ] character that
2737c478bd9Sstevel@tonic-gate * would have been copied from the source, because it is not possible
2747c478bd9Sstevel@tonic-gate * to expand the broad character to its complete form (case 4).
2757c478bd9Sstevel@tonic-gate *
2767c478bd9Sstevel@tonic-gate * b)
2777c478bd9Sstevel@tonic-gate * copywin(s, t, 0, 1, 0, 3, 1, 5, 0)
278*1da57d55SToomas Soome * s t ==> t
2797c478bd9Sstevel@tonic-gate * +------+ +------+ +------+
2807c478bd9Sstevel@tonic-gate * |abcdef| |123456| |123bcd|
2817c478bd9Sstevel@tonic-gate * |ghi{}l| |789012| |789hi#|
2827c478bd9Sstevel@tonic-gate * |mnopqr| |......| |......|
2837c478bd9Sstevel@tonic-gate * +------+ +------+ +------+
2847c478bd9Sstevel@tonic-gate * Same a 5a. but with the right margin.
2857c478bd9Sstevel@tonic-gate */
286