xref: /original-bsd/lib/libcurses/addbytes.c (revision 2f46dd9e)
1 /*
2  * Copyright (c) 1987 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)addbytes.c	5.20 (Berkeley) 02/13/93";
10 #endif	/* not lint */
11 
12 #include <curses.h>
13 #include <termios.h>
14 
15 #define	SYNCH_IN	{y = win->cury; x = win->curx;}
16 #define	SYNCH_OUT	{win->cury = y; win->curx = x;}
17 
18 /*
19  * waddbytes --
20  *	Add the character to the current position in the given window.
21  */
22 int
23 __waddbytes(win, bytes, count, so)
24 	register WINDOW *win;
25 	register const char *bytes;
26 	register int count;
27 	int so;
28 {
29 	static char blanks[] = "        ";
30 	register int c, newx, x, y;
31 	char stand;
32 	__LINE *lp;
33 
34 	SYNCH_IN;
35 
36 #ifdef DEBUG
37 	__TRACE("ADDBYTES('%c') at (%d, %d)\n", c, y, x);
38 #endif
39 	while (count--) {
40 		c = *bytes++;
41 		switch (c) {
42 		case '\t':
43 			SYNCH_OUT;
44 			if (waddbytes(win, blanks, 8 - (x % 8)) == ERR)
45 				return (ERR);
46 			SYNCH_IN;
47 			break;
48 
49 		default:
50 #ifdef DEBUG
51 	__TRACE("ADDBYTES(%0.2o, %d, %d)\n", win, y, x);
52 #endif
53 
54 			lp = win->lines[y];
55 			if (lp->flags & __ISPASTEOL) {
56 				lp->flags &= ~__ISPASTEOL;
57 newline:			if (y == win->maxy - 1) {
58 					if (win->flags & __SCROLLOK) {
59 						SYNCH_OUT;
60 						scroll(win);
61 						SYNCH_IN;
62 						lp = win->lines[y];
63 					        x = 0;
64 					}
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 	__TRACE("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 	__TRACE("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 	__TRACE("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 (__orig_termios.c_oflag & ONLCR)
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