xref: /netbsd-src/lib/libcurses/addbytes.c (revision 8e3f55895396f83834b387f1acb8fab588a016e5)
1*8e3f5589Sjdc /*	$NetBSD: addbytes.c,v 1.18 2000/04/15 22:53:05 jdc Exp $	*/
2716747aaSmikel 
361f28255Scgd /*
4d29088daScgd  * Copyright (c) 1987, 1993, 1994
5019bbd13Scgd  *	The Regents of the University of California.  All rights reserved.
661f28255Scgd  *
761f28255Scgd  * Redistribution and use in source and binary forms, with or without
861f28255Scgd  * modification, are permitted provided that the following conditions
961f28255Scgd  * are met:
1061f28255Scgd  * 1. Redistributions of source code must retain the above copyright
1161f28255Scgd  *    notice, this list of conditions and the following disclaimer.
1261f28255Scgd  * 2. Redistributions in binary form must reproduce the above copyright
1361f28255Scgd  *    notice, this list of conditions and the following disclaimer in the
1461f28255Scgd  *    documentation and/or other materials provided with the distribution.
1561f28255Scgd  * 3. All advertising materials mentioning features or use of this software
1661f28255Scgd  *    must display the following acknowledgement:
1761f28255Scgd  *	This product includes software developed by the University of
1861f28255Scgd  *	California, Berkeley and its contributors.
1961f28255Scgd  * 4. Neither the name of the University nor the names of its contributors
2061f28255Scgd  *    may be used to endorse or promote products derived from this software
2161f28255Scgd  *    without specific prior written permission.
2261f28255Scgd  *
2361f28255Scgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2461f28255Scgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2561f28255Scgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2661f28255Scgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2761f28255Scgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2861f28255Scgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2961f28255Scgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3061f28255Scgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3161f28255Scgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3261f28255Scgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3361f28255Scgd  * SUCH DAMAGE.
3461f28255Scgd  */
3561f28255Scgd 
36716747aaSmikel #include <sys/cdefs.h>
3761f28255Scgd #ifndef lint
38716747aaSmikel #if 0
39d29088daScgd static char sccsid[] = "@(#)addbytes.c	8.4 (Berkeley) 5/4/94";
40716747aaSmikel #else
41*8e3f5589Sjdc __RCSID("$NetBSD: addbytes.c,v 1.18 2000/04/15 22:53:05 jdc Exp $");
42716747aaSmikel #endif
4361f28255Scgd #endif				/* not lint */
4461f28255Scgd 
45d29088daScgd #include "curses.h"
4623464ee5Sblymn #include "curses_private.h"
4761f28255Scgd 
48019bbd13Scgd #define	SYNCH_IN	{y = win->cury; x = win->curx;}
49019bbd13Scgd #define	SYNCH_OUT	{win->cury = y; win->curx = x;}
5075de25bbSalm 
51aaf74682Sblymn #ifndef _CURSES_USE_MACROS
52aaf74682Sblymn 
53aaf74682Sblymn /*
54aaf74682Sblymn  * addbytes --
55aaf74682Sblymn  *      Add the character to the current position in stdscr.
56aaf74682Sblymn  */
57aaf74682Sblymn int
58aaf74682Sblymn addbytes(const char *bytes, int count)
59aaf74682Sblymn {
60aaf74682Sblymn 	return __waddbytes(stdscr, bytes, count, 0);
61aaf74682Sblymn }
62aaf74682Sblymn 
6361f28255Scgd /*
6462a3457dSmycroft  * waddbytes --
6562a3457dSmycroft  *      Add the character to the current position in the given window.
6661f28255Scgd  */
6762a3457dSmycroft int
68aaf74682Sblymn waddbytes(WINDOW *win, const char *bytes, int count)
69aaf74682Sblymn {
70aaf74682Sblymn 	return __waddbytes(win, bytes, count, 0);
71aaf74682Sblymn }
72aaf74682Sblymn 
73aaf74682Sblymn /*
74aaf74682Sblymn  * mvaddbytes --
75aaf74682Sblymn  *      Add the characters to stdscr at the location given.
76aaf74682Sblymn  */
77aaf74682Sblymn int
78aaf74682Sblymn mvaddbytes(int y, int x, const char *bytes, int count)
79aaf74682Sblymn {
80aaf74682Sblymn 	return mvwaddbytes(stdscr, y, x, bytes, count);
81aaf74682Sblymn }
82aaf74682Sblymn 
83aaf74682Sblymn /*
84aaf74682Sblymn  * mvwaddbytes --
85aaf74682Sblymn  *      Add the characters to the given window at the location given.
86aaf74682Sblymn  */
87aaf74682Sblymn int
88aaf74682Sblymn mvwaddbytes(WINDOW *win, int y, int x, const char *bytes, int count)
89aaf74682Sblymn {
90aaf74682Sblymn 	if (wmove(win, y, x) == ERR)
91aaf74682Sblymn 		return ERR;
92aaf74682Sblymn 
93aaf74682Sblymn 	return __waddbytes(win, bytes, count, 0);
94aaf74682Sblymn }
95aaf74682Sblymn 
96aaf74682Sblymn #endif
97aaf74682Sblymn 
98aaf74682Sblymn /*
99aaf74682Sblymn  * waddbytes --
100aaf74682Sblymn  *	Add the character to the current position in the given window.
101aaf74682Sblymn  */
102aaf74682Sblymn int
103aaf74682Sblymn __waddbytes(WINDOW *win, const char *bytes, int count, attr_t attr)
10461f28255Scgd {
10562a3457dSmycroft 	static char	 blanks[] = "        ";
1060b7831a3Sperry 	int		 c, newx, x, y;
10723464ee5Sblymn 	attr_t		 attributes;
108019bbd13Scgd 	__LINE		*lp;
10961f28255Scgd 
11062a3457dSmycroft 	SYNCH_IN;
11162a3457dSmycroft 
112716747aaSmikel 	while (count--) {
113716747aaSmikel 		c = *bytes++;
11462a3457dSmycroft #ifdef DEBUG
11540b39f92Sjdc 		__CTRACE("ADDBYTES('%c', %x) at (%d, %d)\n", c, attr, y, x);
11662a3457dSmycroft #endif
11761f28255Scgd 		switch (c) {
11861f28255Scgd 		case '\t':
11962a3457dSmycroft 			SYNCH_OUT;
12062a3457dSmycroft 			if (waddbytes(win, blanks, 8 - (x % 8)) == ERR)
12162a3457dSmycroft 				return (ERR);
12262a3457dSmycroft 			SYNCH_IN;
12361f28255Scgd 			break;
12461f28255Scgd 
12561f28255Scgd 		default:
12662a3457dSmycroft #ifdef DEBUG
127019bbd13Scgd 			__CTRACE("ADDBYTES(%0.2o, %d, %d)\n", win, y, x);
12861f28255Scgd #endif
129019bbd13Scgd 
130019bbd13Scgd 			lp = win->lines[y];
131019bbd13Scgd 			if (lp->flags & __ISPASTEOL) {
132019bbd13Scgd 				lp->flags &= ~__ISPASTEOL;
133019bbd13Scgd 		newline:	if (y == win->maxy - 1) {
134019bbd13Scgd 					if (win->flags & __SCROLLOK) {
13562a3457dSmycroft 						SYNCH_OUT;
13661f28255Scgd 						scroll(win);
13762a3457dSmycroft 						SYNCH_IN;
138019bbd13Scgd 						lp = win->lines[y];
139019bbd13Scgd 						x = 0;
140d29088daScgd 					} else
141d29088daScgd 						return (ERR);
142019bbd13Scgd 				} else {
143019bbd13Scgd 					y++;
144019bbd13Scgd 					lp = win->lines[y];
145019bbd13Scgd 					x = 0;
146019bbd13Scgd 				}
147019bbd13Scgd 				if (c == '\n')
148019bbd13Scgd 					break;
149019bbd13Scgd 			}
150019bbd13Scgd 
151586d4ce1Smrg 			attributes = '\0';
15223464ee5Sblymn 			if (win->wattr & __STANDOUT || attr & __STANDOUT)
153586d4ce1Smrg 				attributes |= __STANDOUT;
15423464ee5Sblymn 			if (win->wattr & __UNDERSCORE || attr & __UNDERSCORE)
155586d4ce1Smrg 				attributes |= __UNDERSCORE;
15623464ee5Sblymn 			if (win->wattr & __REVERSE || attr & __REVERSE)
157586d4ce1Smrg 				attributes |= __REVERSE;
15823464ee5Sblymn 			if (win->wattr & __BLINK || attr & __BLINK)
159586d4ce1Smrg 				attributes |= __BLINK;
16023464ee5Sblymn 			if (win->wattr & __DIM || attr & __DIM)
161586d4ce1Smrg 				attributes |= __DIM;
16223464ee5Sblymn 			if (win->wattr & __BOLD || attr & __BOLD)
163586d4ce1Smrg 				attributes |= __BOLD;
16423464ee5Sblymn 			if (win->wattr & __BLANK || attr & __BLANK)
165586d4ce1Smrg 				attributes |= __BLANK;
16623464ee5Sblymn 			if (win->wattr & __PROTECT || attr & __PROTECT)
167586d4ce1Smrg 				attributes |= __PROTECT;
16823464ee5Sblymn 			if (win->wattr & __ALTCHARSET || attr & __ALTCHARSET)
16923464ee5Sblymn 				attributes |= __ALTCHARSET;
17040b39f92Sjdc 			if (attr & __COLOR)
17140b39f92Sjdc 				attributes |= attr & __COLOR;
17240b39f92Sjdc 			else if (win->wattr & __COLOR)
17340b39f92Sjdc 				attributes |= win->wattr & __COLOR;
17462a3457dSmycroft #ifdef DEBUG
175019bbd13Scgd 			__CTRACE("ADDBYTES: 1: y = %d, x = %d, firstch = %d, lastch = %d\n",
176586d4ce1Smrg 			    y, x, *win->lines[y]->firstchp,
177586d4ce1Smrg 			    *win->lines[y]->lastchp);
178019bbd13Scgd #endif
179019bbd13Scgd 			if (lp->line[x].ch != c ||
18040b39f92Sjdc 			    lp->line[x].attr != attributes) {
181019bbd13Scgd 				newx = x + win->ch_off;
182*8e3f5589Sjdc 				if (!(lp->flags & __ISDIRTY))
183019bbd13Scgd 					lp->flags |= __ISDIRTY;
184*8e3f5589Sjdc 				/*
185*8e3f5589Sjdc 				 * firstchp/lastchp are shared between
186*8e3f5589Sjdc 				 * parent window and sub-window.
187*8e3f5589Sjdc 				 */
188586d4ce1Smrg 				if (newx < *lp->firstchp)
189019bbd13Scgd 					*lp->firstchp = newx;
190586d4ce1Smrg 				if (newx > *lp->lastchp)
191019bbd13Scgd 					*lp->lastchp = newx;
192019bbd13Scgd #ifdef DEBUG
193019bbd13Scgd 				__CTRACE("ADDBYTES: change gives f/l: %d/%d [%d/%d]\n",
194019bbd13Scgd 				    *lp->firstchp, *lp->lastchp,
195019bbd13Scgd 				    *lp->firstchp - win->ch_off,
196019bbd13Scgd 				    *lp->lastchp - win->ch_off);
197019bbd13Scgd #endif
198019bbd13Scgd 			}
199019bbd13Scgd 			lp->line[x].ch = c;
200586d4ce1Smrg 			if (attributes & __STANDOUT)
201019bbd13Scgd 				lp->line[x].attr |= __STANDOUT;
202019bbd13Scgd 			else
203019bbd13Scgd 				lp->line[x].attr &= ~__STANDOUT;
204586d4ce1Smrg 			if (attributes & __UNDERSCORE)
205586d4ce1Smrg 				lp->line[x].attr |= __UNDERSCORE;
206586d4ce1Smrg 			else
207586d4ce1Smrg 				lp->line[x].attr &= ~__UNDERSCORE;
208586d4ce1Smrg 			if (attributes & __REVERSE)
209586d4ce1Smrg 				lp->line[x].attr |= __REVERSE;
210586d4ce1Smrg 			else
211586d4ce1Smrg 				lp->line[x].attr &= ~__REVERSE;
212586d4ce1Smrg 			if (attributes & __BLINK)
213586d4ce1Smrg 				lp->line[x].attr |= __BLINK;
214586d4ce1Smrg 			else
215586d4ce1Smrg 				lp->line[x].attr &= ~__BLINK;
216586d4ce1Smrg 			if (attributes & __DIM)
217586d4ce1Smrg 				lp->line[x].attr |= __DIM;
218586d4ce1Smrg 			else
219586d4ce1Smrg 				lp->line[x].attr &= ~__DIM;
220586d4ce1Smrg 			if (attributes & __BOLD)
221586d4ce1Smrg 				lp->line[x].attr |= __BOLD;
222586d4ce1Smrg 			else
223586d4ce1Smrg 				lp->line[x].attr &= ~__BOLD;
224586d4ce1Smrg 			if (attributes & __BLANK)
225586d4ce1Smrg 				lp->line[x].attr |= __BLANK;
226586d4ce1Smrg 			else
227586d4ce1Smrg 				lp->line[x].attr &= ~__BLANK;
228586d4ce1Smrg 			if (attributes & __PROTECT)
229586d4ce1Smrg 				lp->line[x].attr |= __PROTECT;
230586d4ce1Smrg 			else
231586d4ce1Smrg 				lp->line[x].attr &= ~__PROTECT;
23223464ee5Sblymn 			if (attributes & __ALTCHARSET)
23323464ee5Sblymn 				lp->line[x].attr |= __ALTCHARSET;
23423464ee5Sblymn 			else
23523464ee5Sblymn 				lp->line[x].attr &= ~__ALTCHARSET;
23640b39f92Sjdc 			if (attributes & __COLOR) {
23740b39f92Sjdc 				lp->line[x].attr &= ~__COLOR;
23840b39f92Sjdc 				lp->line[x].attr |= attributes & __COLOR;
23940b39f92Sjdc 			} else
24040b39f92Sjdc 				lp->line[x].attr &= ~__COLOR;
241019bbd13Scgd 			if (x == win->maxx - 1)
242019bbd13Scgd 				lp->flags |= __ISPASTEOL;
243019bbd13Scgd 			else
244019bbd13Scgd 				x++;
245019bbd13Scgd #ifdef DEBUG
246019bbd13Scgd 			__CTRACE("ADDBYTES: 2: y = %d, x = %d, firstch = %d, lastch = %d\n",
247586d4ce1Smrg 			    y, x, *win->lines[y]->firstchp,
248586d4ce1Smrg 			    *win->lines[y]->lastchp);
24961f28255Scgd #endif
25061f28255Scgd 			break;
25161f28255Scgd 		case '\n':
25262a3457dSmycroft 			SYNCH_OUT;
25361f28255Scgd 			wclrtoeol(win);
25462a3457dSmycroft 			SYNCH_IN;
255019bbd13Scgd 			if (!NONL)
25661f28255Scgd 				x = 0;
25761f28255Scgd 			goto newline;
25861f28255Scgd 		case '\r':
25961f28255Scgd 			x = 0;
26061f28255Scgd 			break;
26161f28255Scgd 		case '\b':
26261f28255Scgd 			if (--x < 0)
26361f28255Scgd 				x = 0;
26461f28255Scgd 			break;
26561f28255Scgd 		}
26661f28255Scgd 	}
26762a3457dSmycroft 	SYNCH_OUT;
26862a3457dSmycroft 	return (OK);
26961f28255Scgd }
270