xref: /illumos-gate/usr/src/lib/libcurses/screen/mbinsshift.c (revision 9b9d39d2a32ff806d2431dbcc50968ef1e6d46b2)
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 /*  Copyright (c) 1988 AT&T */
23 /*    All Rights Reserved   */
24 
25 
26 /*
27  *      Copyright (c) 1997, by Sun Microsystems, Inc.
28  *      All rights reserved.
29  */
30 
31 /*LINTLIBRARY*/
32 
33 #include	<sys/types.h>
34 #include	"curses_inc.h"
35 
36 /*
37  *	Shift right an interval of characters
38  */
39 
40 int
41 _mbinsshift(WINDOW *win, int len)
42 {
43 	int	x, y, maxx,  mv;
44 	chtype	*wcp, *wp, *ep;
45 
46 	y = win->_cury;
47 	x = win->_curx;
48 	maxx = win->_maxx;
49 	wcp  = win->_y[y];
50 
51 	/* ASSERT(!ISCBIT(wcp[x])); */
52 
53 	/* shift up to a whole character */
54 	if (_scrmax > 1) {
55 		wp = wcp + maxx - 1;
56 		if (ISMBIT(*wp)) {
57 			reg chtype	rb;
58 
59 			for (; wp >= wcp; --wp)
60 				if (!ISCBIT(*wp))
61 					break;
62 			if (wp < wcp)
63 				return (ERR);
64 			rb = RBYTE(*wp);
65 			if ((wp + _curs_scrwidth[TYPE(rb)]) > (wcp + maxx))
66 				/*LINTED*/
67 				maxx = (int)(wp - wcp);
68 			}
69 		}
70 
71 	/* see if any data need to move */
72 	if ((mv = maxx - (x+len)) <= 0)
73 		return (OK);
74 
75 	/* the end of the moved interval must be whole */
76 	if (ISCBIT(wcp[x + mv]))
77 		(void) _mbclrch(win, y, x + mv - 1);
78 
79 	/* move data */
80 	ep = wcp + x + len;
81 	for (wp = wcp + maxx - 1; wp >= ep; --wp)
82 		*wp = *(wp - len);
83 
84 	/* clear a possible partial multibyte character */
85 	if (ISMBIT(*wp))
86 		for (ep = wp; ep >= wcp; --ep) {
87 			mv = (int)(ISCBIT(*ep));
88 			*ep = win->_bkgd;
89 			if (!mv)
90 				break;
91 		}
92 
93 	/* update the change structure */
94 	if (x < win->_firstch[y])
95 		/*LINTED*/
96 		win->_firstch[y] = (short)x;
97 	win->_lastch[y] = maxx - 1;
98 
99 	return (OK);
100 }
101