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
42static 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 */
56int
57wscrl(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