xref: /original-bsd/lib/libcurses/addbytes.c (revision f4a18198)
1 /*
2  * Copyright (c) 1987, 1993, 1994
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)addbytes.c	8.4 (Berkeley) 05/04/94";
10 #endif	/* not lint */
11 
12 #include "curses.h"
13 
14 #define	SYNCH_IN	{y = win->cury; x = win->curx;}
15 #define	SYNCH_OUT	{win->cury = y; win->curx = x;}
16 
17 /*
18  * waddbytes --
19  *	Add the character to the current position in the given window.
20  */
21 int
22 __waddbytes(win, bytes, count, so)
23 	register WINDOW *win;
24 	register const char *bytes;
25 	register int count;
26 	int so;
27 {
28 	static char blanks[] = "        ";
29 	register int c, newx, x, y;
30 	char stand;
31 	__LINE *lp;
32 
33 	SYNCH_IN;
34 
35 #ifdef DEBUG
36 	__CTRACE("ADDBYTES('%c') at (%d, %d)\n", c, y, x);
37 #endif
38 	while (count--) {
39 		c = *bytes++;
40 		switch (c) {
41 		case '\t':
42 			SYNCH_OUT;
43 			if (waddbytes(win, blanks, 8 - (x % 8)) == ERR)
44 				return (ERR);
45 			SYNCH_IN;
46 			break;
47 
48 		default:
49 #ifdef DEBUG
50 	__CTRACE("ADDBYTES(%0.2o, %d, %d)\n", win, y, x);
51 #endif
52 
53 			lp = win->lines[y];
54 			if (lp->flags & __ISPASTEOL) {
55 				lp->flags &= ~__ISPASTEOL;
56 newline:			if (y == win->maxy - 1) {
57 					if (win->flags & __SCROLLOK) {
58 						SYNCH_OUT;
59 						scroll(win);
60 						SYNCH_IN;
61 						lp = win->lines[y];
62 					        x = 0;
63 					} else
64 						return (ERR);
65 				} else {
66 					y++;
67 					lp = win->lines[y];
68 					x = 0;
69 				}
70 				if (c == '\n')
71 					break;
72 			}
73 
74 			stand = '\0';
75 			if (win->flags & __WSTANDOUT || so)
76 				stand |= __STANDOUT;
77 #ifdef DEBUG
78 	__CTRACE("ADDBYTES: 1: y = %d, x = %d, firstch = %d, lastch = %d\n",
79 	    y, x, *win->lines[y]->firstchp, *win->lines[y]->lastchp);
80 #endif
81 			if (lp->line[x].ch != c ||
82 			    !(lp->line[x].attr & stand)) {
83 				newx = x + win->ch_off;
84 				if (!(lp->flags & __ISDIRTY)) {
85 					lp->flags |= __ISDIRTY;
86 					*lp->firstchp = *lp->lastchp = newx;
87 				}
88 				else if (newx < *lp->firstchp)
89 					*lp->firstchp = newx;
90 				else if (newx > *lp->lastchp)
91 					*lp->lastchp = newx;
92 #ifdef DEBUG
93 	__CTRACE("ADDBYTES: change gives f/l: %d/%d [%d/%d]\n",
94 	    *lp->firstchp, *lp->lastchp,
95 	    *lp->firstchp - win->ch_off,
96 	    *lp->lastchp - win->ch_off);
97 #endif
98 			}
99 			lp->line[x].ch = c;
100 			if (stand)
101 				lp->line[x].attr |= __STANDOUT;
102 			else
103 				lp->line[x].attr &= ~__STANDOUT;
104 			if (x == win->maxx - 1)
105 				lp->flags |= __ISPASTEOL;
106 			else
107 				x++;
108 #ifdef DEBUG
109 	__CTRACE("ADDBYTES: 2: y = %d, x = %d, firstch = %d, lastch = %d\n",
110 	    y, x, *win->lines[y]->firstchp, *win->lines[y]->lastchp);
111 #endif
112 			break;
113 		case '\n':
114 			SYNCH_OUT;
115 			wclrtoeol(win);
116 			SYNCH_IN;
117 			if (!NONL)
118 				x = 0;
119 			goto newline;
120 		case '\r':
121 			x = 0;
122 			break;
123 		case '\b':
124 			if (--x < 0)
125 				x = 0;
126 			break;
127 		}
128 	}
129 	SYNCH_OUT;
130 	return (OK);
131 }
132