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