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-1999 by Sun Microsystems, Inc.
24  * All rights reserved.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /* LINTLIBRARY */
30 
31 /*
32  * wscrl.c
33  *
34  * XCurses Library
35  *
36  * Copyright 1990, 1995 by Mortice Kern Systems Inc.  All rights reserved.
37  *
38  */
39 
40 #ifdef M_RCSID
41 #ifndef lint
42 static char rcsID[] =
43 "$Header: /team/ps/sun_xcurses/archive/local_changes/xcurses/src/lib/"
44 "libxcurses/src/libc/xcurses/rcs/wscrl.c 1.8 1998/06/04 17:52:07 "
45 "cbates Exp $";
46 #endif
47 #endif
48 
49 #include <private.h>
50 #include <string.h>
51 
52 /*
53  * For positive n scroll the window up n lines (line i+n becomes i);
54  * otherwise scroll the window down n lines.
55  */
56 int
wscrl(WINDOW * w,int n)57 wscrl(WINDOW *w, int n)
58 {
59 	int	start, finish, to;
60 
61 	if (!(w->_flags & W_CAN_SCROLL))
62 		return (ERR);
63 
64 	if (n == 0)
65 		return (OK);
66 
67 	if (w->_parent) {
68 		/* Sub-window should not shuffle pointers (parent owns them) */
69 		int	row;
70 		cchar_t	save;
71 		int	first;
72 
73 		if (n > 0) {
74 			for (row = w->_top; row < w->_bottom; row++) {
75 				if (row < w->_bottom - n) {
76 					if (!w->_line[row+n][0]._f)	{
77 						/*
78 						 * Tail end of
79 						 * a multi-col-char
80 						 */
81 						(void) __m_cc_erase(w, row + n,
82 							0, row + n, 0);
83 					}
84 					/*
85 					 * Erase trailing multi-col-chars
86 					 * where they hang into parent window
87 					 */
88 					first = __m_cc_first(w, row + n,
89 						w->_maxx - 1);
90 					save = w->_line[row + n][first];
91 					(void) __m_cc_erase(w, row + n,
92 						first, row + n, first);
93 					w->_line[row + n][first] = save;
94 					(void) memcpy(w->_line[row],
95 						w->_line[row + n],
96 						sizeof (cchar_t) * w->_maxx);
97 				} else {
98 					(void) __m_cc_erase(w, row, 0,
99 						w->_bottom -1, w->_maxx - 1);
100 					break;
101 				}
102 			}
103 		} else {
104 			abort();
105 		}
106 	} else {
107 		/*
108 		 * Shuffle pointers in order to scroll.  The region
109 		 * from start to finish inclusive will be moved to
110 		 * either the top or bottom of _line[].
111 		 */
112 		if (0 < n) {
113 			start = w->_top;
114 			finish = w->_top + n - 1;
115 			to = w->_bottom;
116 		} else {
117 			start = w->_bottom + n;
118 			finish = w->_bottom - 1;
119 			to = w->_top;
120 		}
121 
122 		/* Blank out new lines. */
123 		(void) __m_cc_erase(w, start, 0, finish, w->_maxx - 1);
124 
125 		/* Scroll lines by shuffling pointers. */
126 		(void) __m_ptr_move((void **) w->_line, w->_maxy,
127 			start, finish, to);
128 	}
129 
130 	if ((w->_flags & W_FULL_WINDOW) &&
131 		w->_top == 0 && w->_bottom == w->_maxy)
132 		w->_scroll += (short) n;
133 	else
134 		w->_scroll = 0;
135 
136 	(void) wtouchln(w, 0, w->_maxy, 1);
137 	wtouchln_hard(w, 0, w->_maxy);
138 
139 #ifdef	BREAKS_fimmedok_fimmedok1_2
140 	w->_flags |= W_FLUSH;
141 #endif	/* BREAKS_fimmedok_fimmedok1_2 */
142 
143 	WSYNC(w);
144 
145 	return (WFLUSH(w));
146 }
147