1 /* $NetBSD: border.c,v 1.10 2007/05/28 15:01:54 blymn Exp $ */ 2 3 /* 4 * Copyright (c) 2000 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Julian Coleman. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 #include <sys/cdefs.h> 40 #ifndef lint 41 __RCSID("$NetBSD: border.c,v 1.10 2007/05/28 15:01:54 blymn Exp $"); 42 #endif /* not lint */ 43 44 #include <stdlib.h> 45 #include <string.h> 46 47 #include "curses.h" 48 #include "curses_private.h" 49 50 #ifndef _CURSES_USE_MACROS 51 52 /* 53 * border -- 54 * Draw a border around stdscr using the specified 55 * delimiting characters. 56 */ 57 int 58 border(chtype left, chtype right, chtype top, chtype bottom, chtype topleft, 59 chtype topright, chtype botleft, chtype botright) 60 { 61 return wborder(stdscr, left, right, top, bottom, topleft, topright, 62 botleft, botright); 63 } 64 65 #endif 66 67 /* 68 * wborder -- 69 * Draw a border around the given window using the specified delimiting 70 * characters. 71 */ 72 int 73 wborder(WINDOW *win, chtype left, chtype right, chtype top, chtype bottom, 74 chtype topleft, chtype topright, chtype botleft, chtype botright) 75 { 76 int endy, endx, i; 77 __LDATA *fp, *lp; 78 79 if (!(left & __CHARTEXT)) 80 left |= ACS_VLINE; 81 if (!(right & __CHARTEXT)) 82 right |= ACS_VLINE; 83 if (!(top & __CHARTEXT)) 84 top |= ACS_HLINE; 85 if (!(bottom & __CHARTEXT)) 86 bottom |= ACS_HLINE; 87 if (!(topleft & __CHARTEXT)) 88 topleft |= ACS_ULCORNER; 89 if (!(topright & __CHARTEXT)) 90 topright |= ACS_URCORNER; 91 if (!(botleft & __CHARTEXT)) 92 botleft |= ACS_LLCORNER; 93 if (!(botright & __CHARTEXT)) 94 botright |= ACS_LRCORNER; 95 96 #ifdef DEBUG 97 __CTRACE(__CTRACE_INPUT, "wborder: left = %c, 0x%x\n", 98 left & __CHARTEXT, left & __ATTRIBUTES); 99 __CTRACE(__CTRACE_INPUT, "wborder: right = %c, 0x%x\n", 100 right & __CHARTEXT, right & __ATTRIBUTES); 101 __CTRACE(__CTRACE_INPUT, "wborder: top = %c, 0x%x\n", 102 top & __CHARTEXT, top & __ATTRIBUTES); 103 __CTRACE(__CTRACE_INPUT, "wborder: bottom = %c, 0x%x\n", 104 bottom & __CHARTEXT, bottom & __ATTRIBUTES); 105 __CTRACE(__CTRACE_INPUT, "wborder: topleft = %c, 0x%x\n", 106 topleft & __CHARTEXT, topleft & __ATTRIBUTES); 107 __CTRACE(__CTRACE_INPUT, "wborder: topright = %c, 0x%x\n", 108 topright & __CHARTEXT, topright & __ATTRIBUTES); 109 __CTRACE(__CTRACE_INPUT, "wborder: botleft = %c, 0x%x\n", 110 botleft & __CHARTEXT, botleft & __ATTRIBUTES); 111 __CTRACE(__CTRACE_INPUT, "wborder: botright = %c, 0x%x\n", 112 botright & __CHARTEXT, botright & __ATTRIBUTES); 113 #endif 114 115 /* Merge window and background attributes */ 116 left |= (left & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; 117 left |= (left & __COLOR) ? (win->battr & ~__COLOR) : win->battr; 118 right |= (right & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; 119 right |= (right & __COLOR) ? (win->battr & ~__COLOR) : win->battr; 120 top |= (top & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; 121 top |= (top & __COLOR) ? (win->battr & ~__COLOR) : win->battr; 122 bottom |= (bottom & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; 123 bottom |= (bottom & __COLOR) ? (win->battr & ~__COLOR) : win->battr; 124 topleft |= (topleft & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; 125 topleft |= (topleft & __COLOR) ? (win->battr & ~__COLOR) : win->battr; 126 topright |= (topright & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; 127 topright |= (topright & __COLOR) ? (win->battr & ~__COLOR) : win->battr; 128 botleft |= (botleft & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; 129 botleft |= (botleft & __COLOR) ? (win->battr & ~__COLOR) : win->battr; 130 botright |= (botright & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; 131 botright |= (botright & __COLOR) ? (win->battr & ~__COLOR) : win->battr; 132 133 endx = win->maxx - 1; 134 endy = win->maxy - 1; 135 fp = win->lines[0]->line; 136 lp = win->lines[endy]->line; 137 138 /* Sides */ 139 for (i = 1; i < endy; i++) { 140 win->lines[i]->line[0].ch = (wchar_t) left & __CHARTEXT; 141 win->lines[i]->line[0].attr = (attr_t) left & __ATTRIBUTES; 142 win->lines[i]->line[endx].ch = (wchar_t) right & __CHARTEXT; 143 win->lines[i]->line[endx].attr = (attr_t) right & __ATTRIBUTES; 144 #ifdef HAVE_WCHAR 145 SET_WCOL(win->lines[i]->line[0], 1); 146 SET_WCOL(win->lines[i]->line[endx], 1); 147 #endif 148 } 149 for (i = 1; i < endx; i++) { 150 fp[i].ch = (wchar_t) top & __CHARTEXT; 151 fp[i].attr = (attr_t) top & __ATTRIBUTES; 152 lp[i].ch = (wchar_t) bottom & __CHARTEXT; 153 lp[i].attr = (attr_t) bottom & __ATTRIBUTES; 154 #ifdef HAVE_WCHAR 155 SET_WCOL(fp[i], 1); 156 SET_WCOL(lp[i], 1); 157 #endif 158 } 159 160 /* Corners */ 161 if (!(win->maxx == LINES && win->maxy == COLS && 162 (win->flags & __SCROLLOK) && (win->flags & __SCROLLWIN))) { 163 fp[0].ch = (wchar_t) topleft & __CHARTEXT; 164 fp[0].attr = (attr_t) topleft & __ATTRIBUTES; 165 fp[endx].ch = (wchar_t) topright & __CHARTEXT; 166 fp[endx].attr = (attr_t) topright & __ATTRIBUTES; 167 lp[0].ch = (wchar_t) botleft & __CHARTEXT; 168 lp[0].attr = (attr_t) botleft & __ATTRIBUTES; 169 lp[endx].ch = (wchar_t) botright & __CHARTEXT; 170 lp[endx].attr = (attr_t) botright & __ATTRIBUTES; 171 #ifdef HAVE_WCHAR 172 SET_WCOL(fp[0], 1); 173 SET_WCOL(fp[endx], 1); 174 SET_WCOL(lp[0], 1); 175 SET_WCOL(lp[endx], 1); 176 #endif 177 } 178 __touchwin(win); 179 return (OK); 180 } 181 182 int border_set(const cchar_t *ls, const cchar_t *rs, const cchar_t *ts, 183 const cchar_t *bs, const cchar_t *tl, const cchar_t *tr, 184 const cchar_t *bl, const cchar_t *br) 185 { 186 #ifndef HAVE_WCHAR 187 return ERR; 188 #else 189 return wborder_set(stdscr, ls, rs, ts, bs, tl, tr, bl, br); 190 #endif /* HAVE_WCHAR */ 191 } 192 193 int wborder_set(WINDOW *win, const cchar_t *ls, const cchar_t *rs, 194 const cchar_t *ts, const cchar_t *bs, 195 const cchar_t *tl, const cchar_t *tr, 196 const cchar_t *bl, const cchar_t *br) 197 { 198 #ifndef HAVE_WCHAR 199 return ERR; 200 #else 201 int endy, endx, i, j, k, cw, pcw, tlcw, blcw, trcw, brcw; 202 cchar_t left, right, bottom, top, topleft, topright, botleft, botright; 203 nschar_t *np, *tnp; 204 205 if ( ls && wcwidth( ls->vals[ 0 ])) 206 memcpy( &left, ls, sizeof( cchar_t )); 207 else 208 setcchar( &left, &WACS_VLINE, win->wattr, 0, NULL ); 209 if ( rs && wcwidth( rs->vals[ 0 ])) 210 memcpy( &right, rs, sizeof( cchar_t )); 211 else 212 setcchar( &right, &WACS_VLINE, win->wattr, 0, NULL ); 213 if ( ts && wcwidth( ts->vals[ 0 ])) 214 memcpy( &top, ts, sizeof( cchar_t )); 215 else 216 setcchar( &top, &WACS_HLINE, win->wattr, 0, NULL ); 217 if ( bs && wcwidth( bs->vals[ 0 ])) 218 memcpy( &bottom, bs, sizeof( cchar_t )); 219 else 220 setcchar( &bottom, &WACS_HLINE, win->wattr, 0, NULL ); 221 if ( tl && wcwidth( tl->vals[ 0 ])) 222 memcpy( &topleft, tl, sizeof( cchar_t )); 223 else 224 setcchar( &topleft, &WACS_ULCORNER, win->wattr, 0, NULL ); 225 if ( tr && wcwidth( tr->vals[ 0 ])) 226 memcpy( &topright, tr, sizeof( cchar_t )); 227 else 228 setcchar( &topright, &WACS_URCORNER, win->wattr, 0, NULL ); 229 if ( bl && wcwidth( bl->vals[ 0 ])) 230 memcpy( &botleft, bl, sizeof( cchar_t )); 231 else 232 setcchar( &botleft, &WACS_LLCORNER, win->wattr, 0, NULL ); 233 if ( br && wcwidth( br->vals[ 0 ])) 234 memcpy( &botright, br, sizeof( cchar_t )); 235 else 236 setcchar( &botright, &WACS_LRCORNER, win->wattr, 0, NULL ); 237 238 #ifdef DEBUG 239 __CTRACE(__CTRACE_INPUT, "wborder_set: left = %c, 0x%x\n", 240 left.vals[0], left.attributes ); 241 __CTRACE(__CTRACE_INPUT, "wborder_set: right = %c, 0x%x\n", 242 right.vals[0], right.attributes ); 243 __CTRACE(__CTRACE_INPUT, "wborder_set: top = %c, 0x%x\n", 244 top.vals[0], top.attributes ); 245 __CTRACE(__CTRACE_INPUT, "wborder_set: bottom = %c, 0x%x\n", 246 bottom.vals[0], bottom.attributes ); 247 __CTRACE(__CTRACE_INPUT, "wborder_set: topleft = %c, 0x%x\n", 248 topleft.vals[0], topleft.attributes ); 249 __CTRACE(__CTRACE_INPUT, "wborder_set: topright = %c, 0x%x\n", 250 topright.vals[0], topright.attributes ); 251 __CTRACE(__CTRACE_INPUT, "wborder_set: botleft = %c, 0x%x\n", 252 botleft.vals[0], botleft.attributes ); 253 __CTRACE(__CTRACE_INPUT, "wborder_set: botright = %c, 0x%x\n", 254 botright.vals[0], botright.attributes ); 255 #endif 256 257 /* Merge window attributes */ 258 left.attributes |= (left.attributes & __COLOR) ? 259 (win->wattr & ~__COLOR) : win->wattr; 260 right.attributes |= (right.attributes & __COLOR) ? 261 (win->wattr & ~__COLOR) : win->wattr; 262 top.attributes |= (top.attributes & __COLOR) ? 263 (win->wattr & ~__COLOR) : win->wattr; 264 bottom.attributes |= (bottom.attributes & __COLOR) ? 265 (win->wattr & ~__COLOR) : win->wattr; 266 topleft.attributes |= (topleft.attributes & __COLOR) ? 267 (win->wattr & ~__COLOR) : win->wattr; 268 topright.attributes |= (topright.attributes & __COLOR) ? 269 (win->wattr & ~__COLOR) : win->wattr; 270 botleft.attributes |= (botleft.attributes & __COLOR) ? 271 (win->wattr & ~__COLOR) : win->wattr; 272 botright.attributes |= (botright.attributes & __COLOR) ? 273 (win->wattr & ~__COLOR) : win->wattr; 274 275 endx = win->maxx - 1; 276 endy = win->maxy - 1; 277 278 /* Sides */ 279 for (i = 1; i < endy; i++) { 280 /* left border */ 281 cw = wcwidth( left.vals[ 0 ]); 282 for ( j = 0; j < cw; j++ ) { 283 win->lines[i]->line[j].ch = left.vals[ 0 ]; 284 win->lines[i]->line[j].attr = left.attributes; 285 np = win->lines[i]->line[j].nsp; 286 if (np) { 287 while ( np ) { 288 tnp = np->next; 289 free( np ); 290 np = tnp; 291 } 292 win->lines[i]->line[j].nsp = NULL; 293 } 294 if ( j ) 295 SET_WCOL( win->lines[i]->line[j], -j ); 296 else { 297 SET_WCOL( win->lines[i]->line[j], cw ); 298 if ( left.elements > 1 ) { 299 for (k = 1; k < left.elements; k++) { 300 np = (nschar_t *)malloc(sizeof(nschar_t)); 301 if (!np) 302 return ERR; 303 np->ch = left.vals[ k ]; 304 np->next = win->lines[i]->line[j].nsp; 305 win->lines[i]->line[j].nsp 306 = np; 307 } 308 } 309 } 310 } 311 for ( j = cw; WCOL( win->lines[i]->line[j]) < 0; j++ ) { 312 #ifdef DEBUG 313 __CTRACE(__CTRACE_INPUT, 314 "wborder_set: clean out partial char[%d]", j); 315 #endif /* DEBUG */ 316 win->lines[i]->line[j].ch = ( wchar_t )btowc(win->bch); 317 if (_cursesi_copy_nsp(win->bnsp, 318 &win->lines[i]->line[j]) == ERR) 319 return ERR; 320 SET_WCOL( win->lines[i]->line[j], 1 ); 321 } 322 /* right border */ 323 cw = wcwidth( right.vals[ 0 ]); 324 pcw = WCOL( win->lines[i]->line[endx - cw]); 325 for ( j = endx - cw + 1; j <= endx; j++ ) { 326 win->lines[i]->line[j].ch = right.vals[ 0 ]; 327 win->lines[i]->line[j].attr = right.attributes; 328 np = win->lines[i]->line[j].nsp; 329 if (np) { 330 while ( np ) { 331 tnp = np->next; 332 free( np ); 333 np = tnp; 334 } 335 win->lines[i]->line[j].nsp = NULL; 336 } 337 if ( j == endx - cw + 1 ) { 338 SET_WCOL( win->lines[i]->line[j], cw ); 339 if ( right.elements > 1 ) { 340 for (k = 1; k < right.elements; k++) { 341 np = (nschar_t *)malloc(sizeof(nschar_t)); 342 if (!np) 343 return ERR; 344 np->ch = right.vals[ k ]; 345 np->next = win->lines[i]->line[j].nsp; 346 win->lines[i]->line[j].nsp 347 = np; 348 } 349 } 350 } else 351 SET_WCOL( win->lines[i]->line[j], 352 endx - cw + 1 - j ); 353 } 354 if ( pcw != 1 ) { 355 #ifdef DEBUG 356 __CTRACE(__CTRACE_INPUT, 357 "wborder_set: clean out partial chars[%d:%d]", 358 endx - cw + pcw, endx - cw ); 359 #endif /* DEBUG */ 360 k = pcw < 0 ? endx -cw + pcw : endx - cw; 361 for ( j = endx - cw; j >= k; j-- ) { 362 win->lines[i]->line[j].ch 363 = (wchar_t)btowc(win->bch); 364 if (_cursesi_copy_nsp(win->bnsp, 365 &win->lines[i]->line[j]) == ERR) 366 return ERR; 367 win->lines[i]->line[j].attr = win->battr; 368 SET_WCOL( win->lines[i]->line[j], 1 ); 369 } 370 } 371 } 372 tlcw = wcwidth( topleft.vals[ 0 ]); 373 blcw = wcwidth( botleft.vals[ 0 ]); 374 trcw = wcwidth( topright.vals[ 0 ]); 375 brcw = wcwidth( botright.vals[ 0 ]); 376 /* upper border */ 377 cw = wcwidth( top.vals[ 0 ]); 378 for (i = tlcw; i <= min( endx - cw, endx - trcw ); i += cw ) { 379 for ( j = 0; j < cw; j++ ) { 380 win->lines[ 0 ]->line[i + j].ch = top.vals[ 0 ]; 381 win->lines[ 0 ]->line[i + j].attr = top.attributes; 382 np = win->lines[ 0 ]->line[i + j].nsp; 383 if (np) { 384 while ( np ) { 385 tnp = np->next; 386 free( np ); 387 np = tnp; 388 } 389 win->lines[ 0 ]->line[i + j].nsp = NULL; 390 } 391 if ( j ) 392 SET_WCOL( win->lines[ 0 ]->line[ i + j ], -j ); 393 else { 394 SET_WCOL( win->lines[ 0 ]->line[ i + j ], cw ); 395 if ( top.elements > 1 ) { 396 for ( k = 1; k < top.elements; k++ ) { 397 np = (nschar_t *)malloc(sizeof(nschar_t)); 398 if (!np) 399 return ERR; 400 np->ch = top.vals[ k ]; 401 np->next = win->lines[0]->line[i + j].nsp; 402 win->lines[0]->line[i + j].nsp 403 = np; 404 } 405 } 406 } 407 } 408 } 409 while ( i <= endx - trcw ) { 410 win->lines[0]->line[i].ch = 411 ( wchar_t )btowc(( int ) win->bch ); 412 if (_cursesi_copy_nsp(win->bnsp, 413 &win->lines[0]->line[i]) == ERR) 414 return ERR; 415 win->lines[ 0 ]->line[ i ].attr = win->battr; 416 SET_WCOL( win->lines[ 0 ]->line[ i ], 1 ); 417 i++; 418 } 419 /* lower border */ 420 for (i = blcw; i <= min( endx - cw, endx - brcw ); i += cw ) { 421 for ( j = 0; j < cw; j++ ) { 422 win->lines[ endy ]->line[i + j].ch = bottom.vals[ 0 ]; 423 win->lines[endy]->line[i + j].attr = bottom.attributes; 424 np = win->lines[ endy ]->line[i + j].nsp; 425 if (np) { 426 while ( np ) { 427 tnp = np->next; 428 free( np ); 429 np = tnp; 430 } 431 win->lines[ endy ]->line[i + j].nsp = NULL; 432 } 433 if ( j ) 434 SET_WCOL( win->lines[endy]->line[i + j], -j); 435 else { 436 SET_WCOL( win->lines[endy]->line[i + j], cw ); 437 if ( bottom.elements > 1 ) { 438 for ( k = 1; k < bottom.elements; 439 k++ ) { 440 if ( !( np = ( nschar_t *)malloc( sizeof( nschar_t )))) 441 return ERR; 442 np->ch = bottom.vals[ k ]; 443 np->next = win->lines[endy]->line[i + j].nsp; 444 win->lines[endy]->line[i + j].nsp = np; 445 } 446 } 447 } 448 } 449 } 450 while ( i <= endx - brcw ) { 451 win->lines[endy]->line[i].ch = 452 (wchar_t)btowc((int) win->bch ); 453 if (_cursesi_copy_nsp(win->bnsp, 454 &win->lines[endy]->line[i]) == ERR) 455 return ERR; 456 win->lines[ endy ]->line[ i ].attr = win->battr; 457 SET_WCOL( win->lines[ endy ]->line[ i ], 1 ); 458 i++; 459 } 460 461 /* Corners */ 462 if (!(win->maxx == LINES && win->maxy == COLS && 463 (win->flags & __SCROLLOK) && (win->flags & __SCROLLWIN))) { 464 for ( i = 0; i < tlcw; i++ ) { 465 win->lines[ 0 ]->line[i].ch = topleft.vals[ 0 ]; 466 win->lines[ 0 ]->line[i].attr = topleft.attributes; 467 np = win->lines[ 0 ]->line[i].nsp; 468 if (np) { 469 while ( np ) { 470 tnp = np->next; 471 free( np ); 472 np = tnp; 473 } 474 win->lines[ 0 ]->line[i].nsp = NULL; 475 } 476 if ( i ) 477 SET_WCOL( win->lines[ 0 ]->line[ i ], -i ); 478 else { 479 SET_WCOL( win->lines[ 0 ]->line[ i ], tlcw ); 480 if ( topleft.elements > 1 ) { 481 for ( k = 1; k < topleft.elements; 482 k++ ) { 483 np = (nschar_t *)malloc(sizeof(nschar_t)); 484 if (!np) 485 return ERR; 486 np->ch = topleft.vals[ k ]; 487 np->next = win->lines[ 0 ]->line[i].nsp; 488 win->lines[ 0 ]->line[i].nsp 489 = np; 490 } 491 } 492 } 493 } 494 for ( i = endx - trcw + 1; i <= endx; i++ ) { 495 win->lines[ 0 ]->line[i].ch = topright.vals[ 0 ]; 496 win->lines[ 0 ]->line[i].attr = topright.attributes; 497 np = win->lines[ 0 ]->line[i].nsp; 498 if (np) { 499 while ( np ) { 500 tnp = np->next; 501 free( np ); 502 np = tnp; 503 } 504 win->lines[ 0 ]->line[i].nsp = NULL; 505 } 506 if ( i == endx - trcw + 1 ) { 507 SET_WCOL( win->lines[ 0 ]->line[ i ], trcw ); 508 if ( topright.elements > 1 ) { 509 for ( k = 1; k < topright.elements; 510 k++ ) { 511 np = (nschar_t *)malloc(sizeof(nschar_t)); 512 if (!np) 513 return ERR; 514 np->ch = topright.vals[ k ]; 515 np->next = win->lines[0]->line[i].nsp; 516 win->lines[ 0 ]->line[i].nsp 517 = np; 518 } 519 } 520 } else 521 SET_WCOL( win->lines[ 0 ]->line[ i ], 522 endx - trcw + 1 - i ); 523 } 524 for ( i = 0; i < blcw; i++ ) { 525 win->lines[ endy ]->line[i].ch = botleft.vals[ 0 ]; 526 win->lines[ endy ]->line[i].attr = botleft.attributes; 527 np = win->lines[ endy ]->line[i].nsp; 528 if (np) { 529 while ( np ) { 530 tnp = np->next; 531 free( np ); 532 np = tnp; 533 } 534 win->lines[ endy ]->line[i].nsp = NULL; 535 } 536 if ( i ) 537 SET_WCOL( win->lines[endy]->line[i], -i ); 538 else { 539 SET_WCOL( win->lines[endy]->line[i], blcw ); 540 if ( botleft.elements > 1 ) { 541 for ( k = 1; k < botleft.elements; 542 k++ ) { 543 np = (nschar_t *)malloc(sizeof(nschar_t)); 544 if (!np) 545 return ERR; 546 np->ch = botleft.vals[ k ]; 547 np->next = win->lines[endy]->line[i].nsp; 548 win->lines[endy]->line[i].nsp 549 = np; 550 } 551 } 552 } 553 } 554 for ( i = endx - brcw + 1; i <= endx; i++ ) { 555 win->lines[ endy ]->line[i].ch = botright.vals[ 0 ]; 556 win->lines[ endy ]->line[i].attr = botright.attributes; 557 np = win->lines[ endy ]->line[i].nsp; 558 if (np) { 559 while ( np ) { 560 tnp = np->next; 561 free( np ); 562 np = tnp; 563 } 564 win->lines[ endy ]->line[i].nsp = NULL; 565 } 566 if ( i == endx - brcw + 1 ) { 567 SET_WCOL( win->lines[ endy ]->line[ i ], 568 brcw ); 569 if ( botright.elements > 1 ) { 570 for ( k = 1; k < botright.elements; k++ ) { 571 np = (nschar_t *)malloc(sizeof(nschar_t)); 572 if (!np) 573 return ERR; 574 np->ch = botright.vals[ k ]; 575 np->next = win->lines[endy]->line[i].nsp; 576 win->lines[endy]->line[i].nsp 577 = np; 578 } 579 } 580 } else 581 SET_WCOL( win->lines[ endy ]->line[ i ], 582 endx - brcw + 1 - i ); 583 } 584 } 585 __touchwin(win); 586 return (OK); 587 #endif /* HAVE_WCHAR */ 588 } 589