addbytes.c revision 1.31 1 /* $NetBSD: addbytes.c,v 1.31 2007/01/21 13:25:36 jdc Exp $ */
2
3 /*
4 * Copyright (c) 1987, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 #include <sys/cdefs.h>
33 #ifndef lint
34 #if 0
35 static char sccsid[] = "@(#)addbytes.c 8.4 (Berkeley) 5/4/94";
36 #else
37 __RCSID("$NetBSD: addbytes.c,v 1.31 2007/01/21 13:25:36 jdc Exp $");
38 #endif
39 #endif /* not lint */
40
41 #include "curses.h"
42 #include "curses_private.h"
43 #ifdef DEBUG
44 #include <assert.h>
45 #endif
46
47 #define SYNCH_IN {y = win->cury; x = win->curx;}
48 #define SYNCH_OUT {win->cury = y; win->curx = x;}
49
50 #ifndef _CURSES_USE_MACROS
51
52 /*
53 * addbytes --
54 * Add the character to the current position in stdscr.
55 */
56 int
57 addbytes(const char *bytes, int count)
58 {
59 return __waddbytes(stdscr, bytes, count, 0);
60 }
61
62 /*
63 * waddbytes --
64 * Add the character to the current position in the given window.
65 */
66 int
67 waddbytes(WINDOW *win, const char *bytes, int count)
68 {
69 return __waddbytes(win, bytes, count, 0);
70 }
71
72 /*
73 * mvaddbytes --
74 * Add the characters to stdscr at the location given.
75 */
76 int
77 mvaddbytes(int y, int x, const char *bytes, int count)
78 {
79 return mvwaddbytes(stdscr, y, x, bytes, count);
80 }
81
82 /*
83 * mvwaddbytes --
84 * Add the characters to the given window at the location given.
85 */
86 int
87 mvwaddbytes(WINDOW *win, int y, int x, const char *bytes, int count)
88 {
89 if (wmove(win, y, x) == ERR)
90 return ERR;
91
92 return __waddbytes(win, bytes, count, 0);
93 }
94
95 #endif
96
97 /*
98 * waddbytes --
99 * Add the character to the current position in the given window.
100 */
101 int
102 __waddbytes(WINDOW *win, const char *bytes, int count, attr_t attr)
103 {
104 static char blanks[] = " ";
105 int c, newx, x, y;
106 attr_t attributes;
107 __LINE *lp;
108 #ifdef DEBUG
109 int i;
110
111 for (i = 0; i < win->maxy; i++) {
112 assert(win->lines[i]->sentinel == SENTINEL_VALUE);
113 }
114 #endif
115
116 SYNCH_IN;
117 lp = win->lines[y];
118
119 while (count--) {
120 c = *bytes++;
121 #ifdef DEBUG
122 __CTRACE(__CTRACE_INPUT, "ADDBYTES('%c', %x) at (%d, %d)\n",
123 c, attr, y, x);
124 #endif
125 switch (c) {
126 case '\t':
127 SYNCH_OUT;
128 if (waddbytes(win, blanks, 8 - (x % 8)) == ERR)
129 return (ERR);
130 SYNCH_IN;
131 break;
132
133 default:
134 #ifdef DEBUG
135 __CTRACE(__CTRACE_INPUT, "ADDBYTES(%p, %d, %d)\n",
136 win, y, x);
137 #endif
138
139 if (lp->flags & __ISPASTEOL) {
140 newline:
141 x = 0;
142 lp->flags &= ~__ISPASTEOL;
143 if (y == win->scr_b) {
144 #ifdef DEBUG
145 __CTRACE(__CTRACE_INPUT,
146 "ADDBYTES - on bottom "
147 "of scrolling region\n");
148 #endif
149 if (!(win->flags & __SCROLLOK))
150 return ERR;
151 SYNCH_OUT;
152 scroll(win);
153 SYNCH_IN;
154 } else {
155 y++;
156 }
157 lp = win->lines[y];
158 if (c == '\n')
159 break;
160 }
161
162 attributes = (win->wattr | attr) &
163 (__ATTRIBUTES & ~__COLOR);
164 if (attr & __COLOR)
165 attributes |= attr & __COLOR;
166 else if (win->wattr & __COLOR)
167 attributes |= win->wattr & __COLOR;
168 #ifdef DEBUG
169 __CTRACE(__CTRACE_INPUT,
170 "ADDBYTES: 1: y = %d, x = %d, firstch = %d, "
171 "lastch = %d\n",
172 y, x, *win->lines[y]->firstchp,
173 *win->lines[y]->lastchp);
174 #endif
175 /*
176 * Always update the change pointers. Otherwise,
177 * we could end up not displaying 'blank' characters
178 * when overlapping windows are displayed.
179 */
180 newx = x + win->ch_off;
181 lp->flags |= __ISDIRTY;
182 /*
183 * firstchp/lastchp are shared between
184 * parent window and sub-window.
185 */
186 if (newx < *lp->firstchp)
187 *lp->firstchp = newx;
188 if (newx > *lp->lastchp)
189 *lp->lastchp = newx;
190 #ifdef DEBUG
191 __CTRACE(__CTRACE_INPUT,
192 "ADDBYTES: change gives f/l: %d/%d [%d/%d]\n",
193 *lp->firstchp, *lp->lastchp,
194 *lp->firstchp - win->ch_off,
195 *lp->lastchp - win->ch_off);
196 #endif
197 if (win->bch != ' ' && c == ' ')
198 lp->line[x].ch = win->bch;
199 else
200 lp->line[x].ch = c;
201 if (attributes & __COLOR)
202 lp->line[x].attr =
203 attributes | (win->battr & ~__COLOR);
204 else
205 lp->line[x].attr = attributes | win->battr;
206 if (x == win->maxx - 1)
207 lp->flags |= __ISPASTEOL;
208 else
209 x++;
210 #ifdef DEBUG
211 __CTRACE(__CTRACE_INPUT,
212 "ADDBYTES: 2: y = %d, x = %d, firstch = %d, "
213 "lastch = %d\n",
214 y, x, *win->lines[y]->firstchp,
215 *win->lines[y]->lastchp);
216 #endif
217 break;
218 case '\n':
219 SYNCH_OUT;
220 wclrtoeol(win);
221 SYNCH_IN;
222 goto newline;
223 case '\r':
224 x = 0;
225 continue;
226 case '\b':
227 if (--x < 0)
228 x = 0;
229 break;
230 }
231 }
232 SYNCH_OUT;
233
234 #ifdef DEBUG
235 for (i = 0; i < win->maxy; i++) {
236 assert(win->lines[i]->sentinel == SENTINEL_VALUE);
237 }
238 #endif
239
240 return (OK);
241 }
242