xref: /netbsd-src/lib/libcurses/addbytes.c (revision c7ba2828300d8ac9a00662b0d4fc0daf4df8ddbb)
1*c7ba2828Sdsl /*	$NetBSD: addbytes.c,v 1.26 2003/06/26 10:22:33 dsl 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*c7ba2828Sdsl __RCSID("$NetBSD: addbytes.c,v 1.26 2003/06/26 10:22:33 dsl Exp $");
42716747aaSmikel #endif
4361f28255Scgd #endif				/* not lint */
4461f28255Scgd 
45d29088daScgd #include "curses.h"
4623464ee5Sblymn #include "curses_private.h"
478d259104Sblymn #ifdef DEBUG
488d259104Sblymn #include <assert.h>
498d259104Sblymn #endif
5061f28255Scgd 
51019bbd13Scgd #define	SYNCH_IN	{y = win->cury; x = win->curx;}
52019bbd13Scgd #define	SYNCH_OUT	{win->cury = y; win->curx = x;}
5375de25bbSalm 
54aaf74682Sblymn #ifndef _CURSES_USE_MACROS
55aaf74682Sblymn 
56aaf74682Sblymn /*
57aaf74682Sblymn  * addbytes --
58aaf74682Sblymn  *      Add the character to the current position in stdscr.
59aaf74682Sblymn  */
60aaf74682Sblymn int
61aaf74682Sblymn addbytes(const char *bytes, int count)
62aaf74682Sblymn {
63aaf74682Sblymn 	return __waddbytes(stdscr, bytes, count, 0);
64aaf74682Sblymn }
65aaf74682Sblymn 
6661f28255Scgd /*
6762a3457dSmycroft  * waddbytes --
6862a3457dSmycroft  *      Add the character to the current position in the given window.
6961f28255Scgd  */
7062a3457dSmycroft int
71aaf74682Sblymn waddbytes(WINDOW *win, const char *bytes, int count)
72aaf74682Sblymn {
73aaf74682Sblymn 	return __waddbytes(win, bytes, count, 0);
74aaf74682Sblymn }
75aaf74682Sblymn 
76aaf74682Sblymn /*
77aaf74682Sblymn  * mvaddbytes --
78aaf74682Sblymn  *      Add the characters to stdscr at the location given.
79aaf74682Sblymn  */
80aaf74682Sblymn int
81aaf74682Sblymn mvaddbytes(int y, int x, const char *bytes, int count)
82aaf74682Sblymn {
83aaf74682Sblymn 	return mvwaddbytes(stdscr, y, x, bytes, count);
84aaf74682Sblymn }
85aaf74682Sblymn 
86aaf74682Sblymn /*
87aaf74682Sblymn  * mvwaddbytes --
88aaf74682Sblymn  *      Add the characters to the given window at the location given.
89aaf74682Sblymn  */
90aaf74682Sblymn int
91aaf74682Sblymn mvwaddbytes(WINDOW *win, int y, int x, const char *bytes, int count)
92aaf74682Sblymn {
93aaf74682Sblymn 	if (wmove(win, y, x) == ERR)
94aaf74682Sblymn 		return ERR;
95aaf74682Sblymn 
96aaf74682Sblymn 	return __waddbytes(win, bytes, count, 0);
97aaf74682Sblymn }
98aaf74682Sblymn 
99aaf74682Sblymn #endif
100aaf74682Sblymn 
101aaf74682Sblymn /*
102aaf74682Sblymn  * waddbytes --
103aaf74682Sblymn  *	Add the character to the current position in the given window.
104aaf74682Sblymn  */
105aaf74682Sblymn int
106aaf74682Sblymn __waddbytes(WINDOW *win, const char *bytes, int count, attr_t attr)
10761f28255Scgd {
10862a3457dSmycroft 	static char	 blanks[] = "        ";
1090b7831a3Sperry 	int		 c, newx, x, y;
11023464ee5Sblymn 	attr_t		 attributes;
111019bbd13Scgd 	__LINE		*lp;
1128d259104Sblymn #ifdef DEBUG
1138d259104Sblymn 	int             i;
1148d259104Sblymn 
1158d259104Sblymn 	for (i = 0; i < win->maxy; i++) {
1168d259104Sblymn 		assert(win->lines[i]->sentinel == SENTINEL_VALUE);
1178d259104Sblymn 	}
1188d259104Sblymn #endif
11961f28255Scgd 
12062a3457dSmycroft 	SYNCH_IN;
1218d259104Sblymn 	lp = win->lines[y];
12262a3457dSmycroft 
123716747aaSmikel 	while (count--) {
124716747aaSmikel 		c = *bytes++;
12562a3457dSmycroft #ifdef DEBUG
12640b39f92Sjdc 		__CTRACE("ADDBYTES('%c', %x) at (%d, %d)\n", c, attr, y, x);
12762a3457dSmycroft #endif
12861f28255Scgd 		switch (c) {
12961f28255Scgd 		case '\t':
13062a3457dSmycroft 			SYNCH_OUT;
13162a3457dSmycroft 			if (waddbytes(win, blanks, 8 - (x % 8)) == ERR)
13262a3457dSmycroft 				return (ERR);
13362a3457dSmycroft 			SYNCH_IN;
13461f28255Scgd 			break;
13561f28255Scgd 
13661f28255Scgd 		default:
13762a3457dSmycroft #ifdef DEBUG
138d75ec818Sdsl 			__CTRACE("ADDBYTES(%p, %d, %d)\n", win, y, x);
13961f28255Scgd #endif
140019bbd13Scgd 
141019bbd13Scgd 			lp = win->lines[y];
142019bbd13Scgd 			if (lp->flags & __ISPASTEOL) {
143*c7ba2828Sdsl 		newline:
144019bbd13Scgd 				lp->flags &= ~__ISPASTEOL;
145*c7ba2828Sdsl 				if (y == win->scr_b) {
1463f9388e3Sjdc #ifdef DEBUG
1473f9388e3Sjdc 			__CTRACE("ADDBYTES - on bottom of scrolling region\n");
1483f9388e3Sjdc #endif
149019bbd13Scgd 					if (win->flags & __SCROLLOK) {
15062a3457dSmycroft 						SYNCH_OUT;
15161f28255Scgd 						scroll(win);
15262a3457dSmycroft 						SYNCH_IN;
153019bbd13Scgd 						lp = win->lines[y];
154019bbd13Scgd 						x = 0;
155d29088daScgd 					} else
156d29088daScgd 						return (ERR);
157019bbd13Scgd 				} else {
158019bbd13Scgd 					y++;
159019bbd13Scgd 					lp = win->lines[y];
160019bbd13Scgd 					x = 0;
161019bbd13Scgd 				}
162019bbd13Scgd 				if (c == '\n')
163019bbd13Scgd 					break;
164019bbd13Scgd 			}
165019bbd13Scgd 
16640add0b9Smycroft 			attributes = (win->wattr | attr) &
16740add0b9Smycroft 			    (__ATTRIBUTES & ~__COLOR);
16840b39f92Sjdc 			if (attr & __COLOR)
16940b39f92Sjdc 				attributes |= attr & __COLOR;
17040b39f92Sjdc 			else if (win->wattr & __COLOR)
17140b39f92Sjdc 				attributes |= win->wattr & __COLOR;
17262a3457dSmycroft #ifdef DEBUG
173019bbd13Scgd 			__CTRACE("ADDBYTES: 1: y = %d, x = %d, firstch = %d, lastch = %d\n",
174586d4ce1Smrg 			    y, x, *win->lines[y]->firstchp,
175586d4ce1Smrg 			    *win->lines[y]->lastchp);
176019bbd13Scgd #endif
17702559eb6Sjdc 			/*
17802559eb6Sjdc 			 * Always update the change pointers.  Otherwise,
17902559eb6Sjdc 			 * we could end up not displaying 'blank' characters
18002559eb6Sjdc 			 * when overlapping windows are displayed.
18102559eb6Sjdc 			 */
182019bbd13Scgd 			newx = x + win->ch_off;
183019bbd13Scgd 			lp->flags |= __ISDIRTY;
1848e3f5589Sjdc 			/*
1858e3f5589Sjdc 			 * firstchp/lastchp are shared between
1868e3f5589Sjdc 			 * parent window and sub-window.
1878e3f5589Sjdc 			 */
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 			lp->line[x].ch = c;
19992a86339Sjdc 			lp->line[x].bch = win->bch;
20040add0b9Smycroft 			lp->line[x].attr = attributes;
20192a86339Sjdc 			lp->line[x].battr = win->battr;
202019bbd13Scgd 			if (x == win->maxx - 1)
203019bbd13Scgd 				lp->flags |= __ISPASTEOL;
204019bbd13Scgd 			else
205019bbd13Scgd 				x++;
206019bbd13Scgd #ifdef DEBUG
207019bbd13Scgd 			__CTRACE("ADDBYTES: 2: y = %d, x = %d, firstch = %d, lastch = %d\n",
208586d4ce1Smrg 			    y, x, *win->lines[y]->firstchp,
209586d4ce1Smrg 			    *win->lines[y]->lastchp);
21061f28255Scgd #endif
21161f28255Scgd 			break;
21261f28255Scgd 		case '\n':
213*c7ba2828Sdsl 			if (!(lp->flags & __ISPASTEOL)) {
21462a3457dSmycroft 				SYNCH_OUT;
21561f28255Scgd 				wclrtoeol(win);
21662a3457dSmycroft 				SYNCH_IN;
217*c7ba2828Sdsl 			}
218606508daSjdc 			if (!__NONL)
21961f28255Scgd 				x = 0;
22061f28255Scgd 			goto newline;
22161f28255Scgd 		case '\r':
22261f28255Scgd 			x = 0;
22361f28255Scgd 			break;
22461f28255Scgd 		case '\b':
22561f28255Scgd 			if (--x < 0)
22661f28255Scgd 				x = 0;
22761f28255Scgd 			break;
22861f28255Scgd 		}
22961f28255Scgd 	}
23062a3457dSmycroft 	SYNCH_OUT;
2318d259104Sblymn 
2328d259104Sblymn #ifdef DEBUG
2338d259104Sblymn 	for (i = 0; i < win->maxy; i++) {
2348d259104Sblymn 		assert(win->lines[i]->sentinel == SENTINEL_VALUE);
2358d259104Sblymn 	}
2368d259104Sblymn #endif
2378d259104Sblymn 
23862a3457dSmycroft 	return (OK);
23961f28255Scgd }
240