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