1 /*
2  * Copyright (c) 1987, 1993, 1994
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 #ifndef lint
31 static char sccsid[] = "@(#)addbytes.c	8.4 (Berkeley) 5/4/94";
32 #endif	/* not lint */
33 
34 #include "curses.h"
35 
36 #define	SYNCH_IN	{y = win->cury; x = win->curx;}
37 #define	SYNCH_OUT	{win->cury = y; win->curx = x;}
38 
39 /*
40  * waddbytes --
41  *	Add the character to the current position in the given window.
42  */
43 int
__waddbytes(win,bytes,count,so)44 __waddbytes(win, bytes, count, so)
45 	register WINDOW *win;
46 	register const char *bytes;
47 	register int count;
48 	int so;
49 {
50 	static char blanks[] = "        ";
51 	register int c, newx, x, y;
52 	char stand;
53 	__LINE *lp;
54 
55 	SYNCH_IN;
56 
57 #ifdef DEBUG
58 	__CTRACE("ADDBYTES('%c') at (%d, %d)\n", c, y, x);
59 #endif
60 	while (count--) {
61 		c = *bytes++;
62 		switch (c) {
63 		case '\t':
64 			SYNCH_OUT;
65 			if (waddbytes(win, blanks, 8 - (x % 8)) == ERR)
66 				return (ERR);
67 			SYNCH_IN;
68 			break;
69 
70 		default:
71 #ifdef DEBUG
72 	__CTRACE("ADDBYTES(%0.2o, %d, %d)\n", win, y, x);
73 #endif
74 
75 			lp = win->lines[y];
76 			if (lp->flags & __ISPASTEOL) {
77 				lp->flags &= ~__ISPASTEOL;
78 newline:			if (y == win->maxy - 1) {
79 					if (win->flags & __SCROLLOK) {
80 						SYNCH_OUT;
81 						scroll(win);
82 						SYNCH_IN;
83 						lp = win->lines[y];
84 					        x = 0;
85 					} else
86 						return (ERR);
87 				} else {
88 					y++;
89 					lp = win->lines[y];
90 					x = 0;
91 				}
92 				if (c == '\n')
93 					break;
94 			}
95 
96 			stand = '\0';
97 			if (win->flags & __WSTANDOUT || so)
98 				stand |= __STANDOUT;
99 #ifdef DEBUG
100 	__CTRACE("ADDBYTES: 1: y = %d, x = %d, firstch = %d, lastch = %d\n",
101 	    y, x, *win->lines[y]->firstchp, *win->lines[y]->lastchp);
102 #endif
103 			if (lp->line[x].ch != c ||
104 			    !(lp->line[x].attr & stand)) {
105 				newx = x + win->ch_off;
106 				if (!(lp->flags & __ISDIRTY)) {
107 					lp->flags |= __ISDIRTY;
108 					*lp->firstchp = *lp->lastchp = newx;
109 				}
110 				else if (newx < *lp->firstchp)
111 					*lp->firstchp = newx;
112 				else if (newx > *lp->lastchp)
113 					*lp->lastchp = newx;
114 #ifdef DEBUG
115 	__CTRACE("ADDBYTES: change gives f/l: %d/%d [%d/%d]\n",
116 	    *lp->firstchp, *lp->lastchp,
117 	    *lp->firstchp - win->ch_off,
118 	    *lp->lastchp - win->ch_off);
119 #endif
120 			}
121 			lp->line[x].ch = c;
122 			if (stand)
123 				lp->line[x].attr |= __STANDOUT;
124 			else
125 				lp->line[x].attr &= ~__STANDOUT;
126 			if (x == win->maxx - 1)
127 				lp->flags |= __ISPASTEOL;
128 			else
129 				x++;
130 #ifdef DEBUG
131 	__CTRACE("ADDBYTES: 2: y = %d, x = %d, firstch = %d, lastch = %d\n",
132 	    y, x, *win->lines[y]->firstchp, *win->lines[y]->lastchp);
133 #endif
134 			break;
135 		case '\n':
136 			SYNCH_OUT;
137 			wclrtoeol(win);
138 			SYNCH_IN;
139 			if (!NONL)
140 				x = 0;
141 			goto newline;
142 		case '\r':
143 			x = 0;
144 			break;
145 		case '\b':
146 			if (--x < 0)
147 				x = 0;
148 			break;
149 		}
150 	}
151 	SYNCH_OUT;
152 	return (OK);
153 }
154