xref: /original-bsd/lib/libcurses/addbytes.c (revision 333da485)
1 /*
2  * Copyright (c) 1987, 1993
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.2 (Berkeley) 01/09/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 					}
64 				} else {
65 					y++;
66 					lp = win->lines[y];
67 					x = 0;
68 				}
69 				if (c == '\n')
70 					break;
71 			}
72 
73 			stand = '\0';
74 			if (win->flags & __WSTANDOUT || so)
75 				stand |= __STANDOUT;
76 #ifdef DEBUG
77 	__CTRACE("ADDBYTES: 1: y = %d, x = %d, firstch = %d, lastch = %d\n",
78 	    y, x, *win->lines[y]->firstchp, *win->lines[y]->lastchp);
79 #endif
80 			if (lp->line[x].ch != c ||
81 			    !(lp->line[x].attr & stand)) {
82 				newx = x + win->ch_off;
83 				if (!(lp->flags & __ISDIRTY)) {
84 					lp->flags |= __ISDIRTY;
85 					*lp->firstchp = *lp->lastchp = newx;
86 				}
87 				else if (newx < *lp->firstchp)
88 					*lp->firstchp = newx;
89 				else if (newx > *lp->lastchp)
90 					*lp->lastchp = newx;
91 #ifdef DEBUG
92 	__CTRACE("ADDBYTES: change gives f/l: %d/%d [%d/%d]\n",
93 	    *lp->firstchp, *lp->lastchp,
94 	    *lp->firstchp - win->ch_off,
95 	    *lp->lastchp - win->ch_off);
96 #endif
97 			}
98 			lp->line[x].ch = c;
99 			if (stand)
100 				lp->line[x].attr |= __STANDOUT;
101 			else
102 				lp->line[x].attr &= ~__STANDOUT;
103 			if (x == win->maxx - 1)
104 				lp->flags |= __ISPASTEOL;
105 			else
106 				x++;
107 #ifdef DEBUG
108 	__CTRACE("ADDBYTES: 2: y = %d, x = %d, firstch = %d, lastch = %d\n",
109 	    y, x, *win->lines[y]->firstchp, *win->lines[y]->lastchp);
110 #endif
111 			break;
112 		case '\n':
113 			SYNCH_OUT;
114 			wclrtoeol(win);
115 			SYNCH_IN;
116 			if (!NONL)
117 				x = 0;
118 			goto newline;
119 		case '\r':
120 			x = 0;
121 			break;
122 		case '\b':
123 			if (--x < 0)
124 				x = 0;
125 			break;
126 		}
127 	}
128 	SYNCH_OUT;
129 	return (OK);
130 }
131