8354 sync regcomp(3C) with upstream (fix make catalog)
[unleashed/tickless.git] / usr / src / lib / libcurses / screen / winsnstr.c
blobe20acd87a0ce9b6da16ac2a19431a6f2d328df4a
1 /*
2 * CDDL HEADER START
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.
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.
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]
20 * CDDL HEADER END
23 * Copyright 1997 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1988 AT&T */
28 /* All Rights Reserved */
31 * University Copyright- Copyright (c) 1982, 1986, 1988
32 * The Regents of the University of California
33 * All Rights Reserved
35 * University Acknowledgment- Portions of this document are derived from
36 * software developed by the University of California, Berkeley, and its
37 * contributors.
40 #pragma ident "%Z%%M% %I% %E% SMI"
42 /*LINTLIBRARY*/
44 #include <sys/types.h>
45 #include "curses_inc.h"
48 * Insert to 'win' at most n chars of a string
49 * starting at (cury, curx). However, if n <= 0,
50 * insert the entire string.
51 * \n, \t, \r, \b are treated in the same way
52 * as other control chars.
55 int
56 winsnstr(WINDOW *win, char *tsp, int n)
58 chtype *wcp;
59 int x, cury, endx, maxx, len;
60 bool savscrl, savsync, savimmed;
61 short savx, savy;
62 unsigned char *sp = (unsigned char *)tsp;
64 /* only insert at the start of a character */
65 win->_nbyte = -1;
66 win->_insmode = TRUE;
67 if (_scrmax > 1 && _mbvalid(win) == ERR)
68 return (ERR);
70 if (n < 0)
71 n = MAXINT;
73 /* compute total length of the insertion */
74 endx = win->_curx;
75 maxx = win->_maxx;
76 for (x = 0; sp[x] != '\0' && x < n && endx < maxx; ++x) {
77 len = (sp[x] < ' '|| sp[x] == _CTRL('?')) ? 2 : 1;
79 if (ISMBIT(sp[x])) {
80 int m, k, ty;
81 chtype c;
83 /* see if the entire character is defined */
84 c = RBYTE(sp[x]);
85 ty = TYPE(c);
86 m = x + cswidth[ty] - (ty == 0 ? 1 : 0);
87 for (k = x + 1; sp[k] != '\0' && k <= m; ++k) {
88 c = RBYTE(sp[k]);
89 if (TYPE(c) != 0)
90 break;
92 if (k <= m)
93 break;
94 /* recompute # of columns used */
95 len = _curs_scrwidth[ty];
96 /* skip an appropriate number of bytes */
97 x = m;
100 if ((endx += len) > maxx) {
101 endx -= len;
102 break;
106 /* length of chars to be shifted */
107 if ((len = endx - win->_curx) <= 0)
108 return (ERR);
110 /* number of chars insertible */
111 n = x;
113 /* shift data */
114 cury = win->_cury;
116 if (_mbinsshift(win, len) == ERR)
117 return (ERR);
119 /* insert new data */
120 wcp = win->_y[cury] + win->_curx;
122 /* act as if we are adding characters */
123 savx = win->_curx;
124 savy = win->_cury;
125 win->_insmode = FALSE;
126 savscrl = win->_scroll;
127 savimmed = win->_immed;
128 savsync = win->_sync;
129 win->_scroll = win->_sync;
131 for (; n > 0; --n, ++sp) {
132 /* multi-byte characters */
133 if (_mbtrue && ISMBIT(*sp)) {
134 (void) _mbaddch(win, A_NORMAL, RBYTE(*sp));
135 wcp = win->_y[cury] + win->_curx;
136 continue;
138 if (_scrmax > 1 && ISMBIT(*wcp))
139 (void) _mbclrch(win, cury, win->_curx);
140 /* single byte character */
141 win->_nbyte = -1;
143 if (*sp < ' ' || *sp == _CTRL('?')) {
144 *wcp++ = _CHAR('^') | win->_attrs;
145 *wcp = _CHAR(_UNCTRL(*sp)) | win->_attrs;
146 } else
147 *wcp = _CHAR(*sp) | win->_attrs;
148 win->_curx += (*sp < ' ' || *sp == _CTRL('?')) ? 2 : 1;
149 ++wcp;
151 win->_curx = savx;
152 win->_cury = savy;
154 /* update the change structure */
155 if (win->_firstch[cury] > win->_curx)
156 win->_firstch[cury] = win->_curx;
157 win->_lastch[cury] = maxx - 1;
159 win->_flags |= _WINCHANGED;
161 win->_scroll = savscrl;
162 win->_sync = savsync;
163 win->_immed = savimmed;
165 if (win->_sync)
166 wsyncup(win);
167 return (win->_immed ? wrefresh(win) : OK);