1 /* $NetBSD: addbytes.c,v 1.26 2003/06/26 10:22:33 dsl 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.26 2003/06/26 10:22:33 dsl 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(%p, %d, %d)\n", win, y, x); 139 #endif 140 141 lp = win->lines[y]; 142 if (lp->flags & __ISPASTEOL) { 143 newline: 144 lp->flags &= ~__ISPASTEOL; 145 if (y == win->scr_b) { 146 #ifdef DEBUG 147 __CTRACE("ADDBYTES - on bottom of scrolling region\n"); 148 #endif 149 if (win->flags & __SCROLLOK) { 150 SYNCH_OUT; 151 scroll(win); 152 SYNCH_IN; 153 lp = win->lines[y]; 154 x = 0; 155 } else 156 return (ERR); 157 } else { 158 y++; 159 lp = win->lines[y]; 160 x = 0; 161 } 162 if (c == '\n') 163 break; 164 } 165 166 attributes = (win->wattr | attr) & 167 (__ATTRIBUTES & ~__COLOR); 168 if (attr & __COLOR) 169 attributes |= attr & __COLOR; 170 else if (win->wattr & __COLOR) 171 attributes |= win->wattr & __COLOR; 172 #ifdef DEBUG 173 __CTRACE("ADDBYTES: 1: y = %d, x = %d, firstch = %d, lastch = %d\n", 174 y, x, *win->lines[y]->firstchp, 175 *win->lines[y]->lastchp); 176 #endif 177 /* 178 * Always update the change pointers. Otherwise, 179 * we could end up not displaying 'blank' characters 180 * when overlapping windows are displayed. 181 */ 182 newx = x + win->ch_off; 183 lp->flags |= __ISDIRTY; 184 /* 185 * firstchp/lastchp are shared between 186 * parent window and sub-window. 187 */ 188 if (newx < *lp->firstchp) 189 *lp->firstchp = newx; 190 if (newx > *lp->lastchp) 191 *lp->lastchp = newx; 192 #ifdef DEBUG 193 __CTRACE("ADDBYTES: change gives f/l: %d/%d [%d/%d]\n", 194 *lp->firstchp, *lp->lastchp, 195 *lp->firstchp - win->ch_off, 196 *lp->lastchp - win->ch_off); 197 #endif 198 lp->line[x].ch = c; 199 lp->line[x].bch = win->bch; 200 lp->line[x].attr = attributes; 201 lp->line[x].battr = win->battr; 202 if (x == win->maxx - 1) 203 lp->flags |= __ISPASTEOL; 204 else 205 x++; 206 #ifdef DEBUG 207 __CTRACE("ADDBYTES: 2: y = %d, x = %d, firstch = %d, lastch = %d\n", 208 y, x, *win->lines[y]->firstchp, 209 *win->lines[y]->lastchp); 210 #endif 211 break; 212 case '\n': 213 if (!(lp->flags & __ISPASTEOL)) { 214 SYNCH_OUT; 215 wclrtoeol(win); 216 SYNCH_IN; 217 } 218 if (!__NONL) 219 x = 0; 220 goto newline; 221 case '\r': 222 x = 0; 223 break; 224 case '\b': 225 if (--x < 0) 226 x = 0; 227 break; 228 } 229 } 230 SYNCH_OUT; 231 232 #ifdef DEBUG 233 for (i = 0; i < win->maxy; i++) { 234 assert(win->lines[i]->sentinel == SENTINEL_VALUE); 235 } 236 #endif 237 238 return (OK); 239 } 240