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