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 1997 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*	Copyright (c) 1988 AT&T	*/
28 /*	  All Rights Reserved	*/
29 
30 /*
31  * University Copyright- Copyright (c) 1982, 1986, 1988
32  * The Regents of the University of California
33  * All Rights Reserved
34  *
35  * University Acknowledgment- Portions of this document are derived from
36  * software developed by the University of California, Berkeley, and its
37  * contributors.
38  */
39 
40 #pragma ident	"%Z%%M%	%I%	%E% SMI"
41 
42 /*LINTLIBRARY*/
43 
44 #include	<sys/types.h>
45 #include	"curses_inc.h"
46 
47 /*
48  * This routine prints the character in the current position.
49  * Think of it as putc.
50  */
51 
52 int
53 waddch(WINDOW *win, chtype c)
54 {
55 	short	x = win->_curx;
56 	short	y = win->_cury;
57 	chtype	rawc = _CHAR(c);
58 	chtype	rawattrs = _ATTR(c);
59 	int	rv = OK;
60 	bool	savimmed = win->_immed;
61 	bool	savsync = win->_sync;
62 
63 	win->_immed = win->_sync = FALSE;
64 
65 #ifdef	DEBUG
66 	if (outf)
67 		if (c == rawc)
68 			fprintf(outf, "'%c'", rawc);
69 		else
70 			fprintf(outf, "'%c' %o, raw %o", c, c, rawc);
71 #endif	/* DEBUG */
72 
73 	win->_insmode = FALSE;
74 	if (_scrmax > 1 && _mbvalid(win) == ERR)
75 		goto next;
76 	if (_mbtrue && ISMBIT(rawc)) {
77 		rv = _mbaddch(win, rawattrs, RBYTE(rawc));
78 		win->_immed = savimmed;
79 		win->_sync = savsync;
80 		goto nextw;
81 	}
82 
83 	switch (rawc) {
84 		case '\n':
85 			(void) wclrtoeol(win);
86 			goto new_line;
87 		case '\r':
88 			goto move_to_begin_line;
89 		case '\b':
90 			if (--x < 0)
91 move_to_begin_line:
92 				x = 0;
93 			win->_curx = x;
94 			win->_flags |= _WINMOVED;
95 			goto out_move_only;
96 		default:
97 			if (rawc < ' ' || rawc == _CTRL('?')) {
98 				if (rawc == '\t') {
99 					int	newx;
100 					chtype	space = ' ' | rawattrs;
101 
102 					if ((newx = x + (TABSIZE -
103 					    (x % TABSIZE))) > win->_maxx)
104 						newx = win->_maxx;
105 						for (; x < newx; x++)
106 							if (waddch(win,
107 							    space) == ERR)
108 								goto next;
109 				} else {
110 					if ((waddch(win, (chtype)
111 					    '^'|rawattrs) == ERR) ||
112 					    (waddch(win, (chtype)
113 					    _UNCTRL(rawc)|rawattrs) == ERR)) {
114 next :
115 						rv = ERR;
116 				}
117 			}
118 			x = win->_curx;
119 			y = win->_cury;
120 			win->_immed = savimmed;
121 			win->_sync = savsync;
122 			break;
123 		}
124 #ifdef	DEBUG
125 		if ((win->_attrs) && outf)
126 			fprintf(outf, "(attrs %o, %o=>%o)", win->_attrs,
127 			    c, c | win->_attrs);
128 #endif	/* DEBUG */
129 
130 		/* clear any partial multi-column character */
131 		if (_scrmax > 1 && ISMBIT(win->_y[y][x]) &&
132 		    (rv = _mbclrch(win, y, x)) == ERR) {
133 			x = win->_curx;
134 			y = win->_cury;
135 			win->_immed = savimmed;
136 			win->_sync = savsync;
137 			break;
138 		}
139 
140 		if ((c = _WCHAR(win, c)|rawattrs) != win->_y[y][x]) {
141 			if (x < win->_firstch[y])
142 				win->_firstch[y] = x;
143 			if (x > win->_lastch[y])
144 				win->_lastch[y] = x;
145 			win->_y[y][x] = c;
146 #ifdef	_VR3_COMPAT_CODE
147 			if (_y16update)
148 				/* LINTED */
149 				win->_y16[y][x] = _TO_OCHTYPE(c);
150 #endif	/* _VR3_COMPAT_CODE */
151 		}
152 		if (++x == win->_maxx) {
153 new_line:
154 			if (y == win->_bmarg) {
155 				if (wscrl(win, 1) == ERR) {
156 					rv = ERR;
157 					if (x == win->_maxx)
158 						--x;
159 #ifdef	DEBUG
160 					if (outf) {
161 						int	i;
162 
163 						fprintf(outf, "ERR because "
164 						    "(%d, %d) > (%d, %d)\n",
165 						    x, y, win->_maxx,
166 						    win->_maxy);
167 						fprintf(outf, "line: '");
168 						for (i = 0; i < win->_maxy;
169 						    i++)
170 							fprintf(outf, "%c",
171 							    win->_y[y-1][i]);
172 						fprintf(outf, "'\n");
173 					}
174 #endif	/* DEBUG */
175 					break;
176 				} else
177 					savimmed = 1;
178 			} else
179 				y++;
180 				x = 0;
181 		} else
182 			savimmed += 2;
183 #ifdef	FULLDEBUG
184 		if (outf)
185 			fprintf(outf, "ADDCH: 2: y = %d, x = %d, "
186 			    "firstch = %d, lastch = %d\n", y, x,
187 			    win->_firstch[y], win->_lastch[y]);
188 #endif	/* FULLDEBUG */
189 		break;
190 	}
191 	win->_cury = y;
192 	win->_curx = x;
193 
194 nextw:
195 	/* sync with ancestor structures */
196 	if (win->_sync)
197 		wsyncup(win);
198 
199 	if (savimmed == 3)
200 		return ((*_quick_ptr)(win, c));
201 
202 	win->_flags |= _WINCHANGED;
203 
204 out_move_only:
205 
206 	return ((savimmed == 1) ? wrefresh(win) : rv);
207 }
208