1 /* $NetBSD: border.c,v 1.14 2010/12/25 09:59:52 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 * 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.14 2010/12/25 09:59:52 blymn 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 #ifndef HAVE_WCHAR 70 int endy, endx, i; 71 __LDATA *fp, *lp; 72 73 if (!(left & __CHARTEXT)) 74 left |= ACS_VLINE; 75 if (!(right & __CHARTEXT)) 76 right |= ACS_VLINE; 77 if (!(top & __CHARTEXT)) 78 top |= ACS_HLINE; 79 if (!(bottom & __CHARTEXT)) 80 bottom |= ACS_HLINE; 81 if (!(topleft & __CHARTEXT)) 82 topleft |= ACS_ULCORNER; 83 if (!(topright & __CHARTEXT)) 84 topright |= ACS_URCORNER; 85 if (!(botleft & __CHARTEXT)) 86 botleft |= ACS_LLCORNER; 87 if (!(botright & __CHARTEXT)) 88 botright |= ACS_LRCORNER; 89 90 #ifdef DEBUG 91 __CTRACE(__CTRACE_INPUT, "wborder: left = %c, 0x%x\n", 92 left & __CHARTEXT, left & __ATTRIBUTES); 93 __CTRACE(__CTRACE_INPUT, "wborder: right = %c, 0x%x\n", 94 right & __CHARTEXT, right & __ATTRIBUTES); 95 __CTRACE(__CTRACE_INPUT, "wborder: top = %c, 0x%x\n", 96 top & __CHARTEXT, top & __ATTRIBUTES); 97 __CTRACE(__CTRACE_INPUT, "wborder: bottom = %c, 0x%x\n", 98 bottom & __CHARTEXT, bottom & __ATTRIBUTES); 99 __CTRACE(__CTRACE_INPUT, "wborder: topleft = %c, 0x%x\n", 100 topleft & __CHARTEXT, topleft & __ATTRIBUTES); 101 __CTRACE(__CTRACE_INPUT, "wborder: topright = %c, 0x%x\n", 102 topright & __CHARTEXT, topright & __ATTRIBUTES); 103 __CTRACE(__CTRACE_INPUT, "wborder: botleft = %c, 0x%x\n", 104 botleft & __CHARTEXT, botleft & __ATTRIBUTES); 105 __CTRACE(__CTRACE_INPUT, "wborder: botright = %c, 0x%x\n", 106 botright & __CHARTEXT, botright & __ATTRIBUTES); 107 #endif 108 109 /* Merge window and background attributes */ 110 left |= (left & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; 111 left |= (left & __COLOR) ? (win->battr & ~__COLOR) : win->battr; 112 right |= (right & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; 113 right |= (right & __COLOR) ? (win->battr & ~__COLOR) : win->battr; 114 top |= (top & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; 115 top |= (top & __COLOR) ? (win->battr & ~__COLOR) : win->battr; 116 bottom |= (bottom & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; 117 bottom |= (bottom & __COLOR) ? (win->battr & ~__COLOR) : win->battr; 118 topleft |= (topleft & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; 119 topleft |= (topleft & __COLOR) ? (win->battr & ~__COLOR) : win->battr; 120 topright |= (topright & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; 121 topright |= (topright & __COLOR) ? (win->battr & ~__COLOR) : win->battr; 122 botleft |= (botleft & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; 123 botleft |= (botleft & __COLOR) ? (win->battr & ~__COLOR) : win->battr; 124 botright |= (botright & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; 125 botright |= (botright & __COLOR) ? (win->battr & ~__COLOR) : win->battr; 126 127 endx = win->maxx - 1; 128 endy = win->maxy - 1; 129 fp = win->alines[0]->line; 130 lp = win->alines[endy]->line; 131 132 /* Sides */ 133 for (i = 1; i < endy; i++) { 134 win->alines[i]->line[0].ch = (wchar_t) left & __CHARTEXT; 135 win->alines[i]->line[0].attr = (attr_t) left & __ATTRIBUTES; 136 win->alines[i]->line[endx].ch = (wchar_t) right & __CHARTEXT; 137 win->alines[i]->line[endx].attr = (attr_t) right & __ATTRIBUTES; 138 } 139 for (i = 1; i < endx; i++) { 140 fp[i].ch = (wchar_t) top & __CHARTEXT; 141 fp[i].attr = (attr_t) top & __ATTRIBUTES; 142 lp[i].ch = (wchar_t) bottom & __CHARTEXT; 143 lp[i].attr = (attr_t) bottom & __ATTRIBUTES; 144 } 145 146 /* Corners */ 147 if (!(win->maxx == LINES && win->maxy == COLS && 148 (win->flags & __SCROLLOK) && (win->flags & __SCROLLWIN))) { 149 fp[0].ch = (wchar_t) topleft & __CHARTEXT; 150 fp[0].attr = (attr_t) topleft & __ATTRIBUTES; 151 fp[endx].ch = (wchar_t) topright & __CHARTEXT; 152 fp[endx].attr = (attr_t) topright & __ATTRIBUTES; 153 lp[0].ch = (wchar_t) botleft & __CHARTEXT; 154 lp[0].attr = (attr_t) botleft & __ATTRIBUTES; 155 lp[endx].ch = (wchar_t) botright & __CHARTEXT; 156 lp[endx].attr = (attr_t) botright & __ATTRIBUTES; 157 } 158 __touchwin(win); 159 return (OK); 160 #else /* HAVE_WCHAR */ 161 cchar_t ls, rs, ts, bs, tl, tr, bl, br; 162 cchar_t *lsp, *rsp, *tsp, *bsp, *tlp, *trp, *blp, *brp; 163 164 #define S(in, out, def) \ 165 if (in & __CHARTEXT) { \ 166 __cursesi_chtype_to_cchar(in, &out); \ 167 } else { \ 168 memcpy(&out, def, sizeof(cchar_t)); \ 169 out.attributes |= in & __ATTRIBUTES; \ 170 } \ 171 out##p = &out; 172 173 S(left, ls, WACS_VLINE); 174 S(right, rs, WACS_VLINE); 175 S(top, ts, WACS_HLINE); 176 S(bottom, bs, WACS_HLINE); 177 S(topleft, tl, WACS_ULCORNER); 178 S(topright, tr, WACS_URCORNER); 179 S(botleft, bl, WACS_LLCORNER); 180 S(botright, br, WACS_LRCORNER); 181 #undef S 182 return wborder_set(win, lsp, rsp, tsp, bsp, tlp, trp, blp, brp); 183 #endif /* HAVE_WCHAR */ 184 } 185 186 int border_set(const cchar_t *ls, const cchar_t *rs, const cchar_t *ts, 187 const cchar_t *bs, const cchar_t *tl, const cchar_t *tr, 188 const cchar_t *bl, const cchar_t *br) 189 { 190 #ifndef HAVE_WCHAR 191 return ERR; 192 #else 193 return wborder_set(stdscr, ls, rs, ts, bs, tl, tr, bl, br); 194 #endif /* HAVE_WCHAR */ 195 } 196 197 int wborder_set(WINDOW *win, const cchar_t *ls, const cchar_t *rs, 198 const cchar_t *ts, const cchar_t *bs, 199 const cchar_t *tl, const cchar_t *tr, 200 const cchar_t *bl, const cchar_t *br) 201 { 202 #ifndef HAVE_WCHAR 203 return ERR; 204 #else 205 int endy, endx, i, j, k, cw, pcw, tlcw, blcw, trcw, brcw; 206 cchar_t left, right, bottom, top, topleft, topright, botleft, botright; 207 nschar_t *np, *tnp; 208 209 if ( ls && wcwidth( ls->vals[ 0 ])) 210 memcpy( &left, ls, sizeof( cchar_t )); 211 else 212 memcpy( &left, WACS_VLINE, sizeof( cchar_t )); 213 if ( rs && wcwidth( rs->vals[ 0 ])) 214 memcpy( &right, rs, sizeof( cchar_t )); 215 else 216 memcpy( &right, WACS_VLINE, sizeof( cchar_t )); 217 if ( ts && wcwidth( ts->vals[ 0 ])) 218 memcpy( &top, ts, sizeof( cchar_t )); 219 else 220 memcpy( &top, WACS_HLINE, sizeof( cchar_t )); 221 if ( bs && wcwidth( bs->vals[ 0 ])) 222 memcpy( &bottom, bs, sizeof( cchar_t )); 223 else 224 memcpy( &bottom, WACS_HLINE, sizeof( cchar_t )); 225 if ( tl && wcwidth( tl->vals[ 0 ])) 226 memcpy( &topleft, tl, sizeof( cchar_t )); 227 else 228 memcpy( &topleft, WACS_ULCORNER, sizeof( cchar_t )); 229 if ( tr && wcwidth( tr->vals[ 0 ])) 230 memcpy( &topright, tr, sizeof( cchar_t )); 231 else 232 memcpy( &topright, WACS_URCORNER, sizeof( cchar_t )); 233 if ( bl && wcwidth( bl->vals[ 0 ])) 234 memcpy( &botleft, bl, sizeof( cchar_t )); 235 else 236 memcpy( &botleft, WACS_LLCORNER, sizeof( cchar_t )); 237 if ( br && wcwidth( br->vals[ 0 ])) 238 memcpy( &botright, br, sizeof( cchar_t )); 239 else 240 memcpy( &botright, WACS_LRCORNER, sizeof( cchar_t )); 241 242 #ifdef DEBUG 243 __CTRACE(__CTRACE_INPUT, "wborder_set: left = %c, 0x%x\n", 244 left.vals[0], left.attributes ); 245 __CTRACE(__CTRACE_INPUT, "wborder_set: right = %c, 0x%x\n", 246 right.vals[0], right.attributes ); 247 __CTRACE(__CTRACE_INPUT, "wborder_set: top = %c, 0x%x\n", 248 top.vals[0], top.attributes ); 249 __CTRACE(__CTRACE_INPUT, "wborder_set: bottom = %c, 0x%x\n", 250 bottom.vals[0], bottom.attributes ); 251 __CTRACE(__CTRACE_INPUT, "wborder_set: topleft = %c, 0x%x\n", 252 topleft.vals[0], topleft.attributes ); 253 __CTRACE(__CTRACE_INPUT, "wborder_set: topright = %c, 0x%x\n", 254 topright.vals[0], topright.attributes ); 255 __CTRACE(__CTRACE_INPUT, "wborder_set: botleft = %c, 0x%x\n", 256 botleft.vals[0], botleft.attributes ); 257 __CTRACE(__CTRACE_INPUT, "wborder_set: botright = %c, 0x%x\n", 258 botright.vals[0], botright.attributes ); 259 #endif 260 261 /* Merge window attributes */ 262 left.attributes |= (left.attributes & __COLOR) ? 263 (win->wattr & ~__COLOR) : win->wattr; 264 right.attributes |= (right.attributes & __COLOR) ? 265 (win->wattr & ~__COLOR) : win->wattr; 266 top.attributes |= (top.attributes & __COLOR) ? 267 (win->wattr & ~__COLOR) : win->wattr; 268 bottom.attributes |= (bottom.attributes & __COLOR) ? 269 (win->wattr & ~__COLOR) : win->wattr; 270 topleft.attributes |= (topleft.attributes & __COLOR) ? 271 (win->wattr & ~__COLOR) : win->wattr; 272 topright.attributes |= (topright.attributes & __COLOR) ? 273 (win->wattr & ~__COLOR) : win->wattr; 274 botleft.attributes |= (botleft.attributes & __COLOR) ? 275 (win->wattr & ~__COLOR) : win->wattr; 276 botright.attributes |= (botright.attributes & __COLOR) ? 277 (win->wattr & ~__COLOR) : win->wattr; 278 279 endx = win->maxx - 1; 280 endy = win->maxy - 1; 281 282 /* Sides */ 283 for (i = 1; i < endy; i++) { 284 /* left border */ 285 cw = wcwidth( left.vals[ 0 ]); 286 if (cw < 0) 287 cw = 1; 288 for ( j = 0; j < cw; j++ ) { 289 win->alines[i]->line[j].ch = left.vals[ 0 ]; 290 win->alines[i]->line[j].attr = left.attributes; 291 np = win->alines[i]->line[j].nsp; 292 if (np) { 293 while ( np ) { 294 tnp = np->next; 295 free( np ); 296 np = tnp; 297 } 298 win->alines[i]->line[j].nsp = NULL; 299 } 300 if ( j ) 301 SET_WCOL( win->alines[i]->line[j], -j ); 302 else { 303 SET_WCOL( win->alines[i]->line[j], cw ); 304 if ( left.elements > 1 ) { 305 for (k = 1; k < left.elements; k++) { 306 np = (nschar_t *)malloc(sizeof(nschar_t)); 307 if (!np) 308 return ERR; 309 np->ch = left.vals[ k ]; 310 np->next = win->alines[i]->line[j].nsp; 311 win->alines[i]->line[j].nsp 312 = np; 313 } 314 } 315 } 316 } 317 for ( j = cw; WCOL( win->alines[i]->line[j]) < 0; j++ ) { 318 #ifdef DEBUG 319 __CTRACE(__CTRACE_INPUT, 320 "wborder_set: clean out partial char[%d]", j); 321 #endif /* DEBUG */ 322 win->alines[i]->line[j].ch = ( wchar_t )btowc(win->bch); 323 if (_cursesi_copy_nsp(win->bnsp, 324 &win->alines[i]->line[j]) == ERR) 325 return ERR; 326 SET_WCOL( win->alines[i]->line[j], 1 ); 327 } 328 /* right border */ 329 cw = wcwidth( right.vals[ 0 ]); 330 if (cw < 0) 331 cw = 1; 332 pcw = WCOL( win->alines[i]->line[endx - cw]); 333 for ( j = endx - cw + 1; j <= endx; j++ ) { 334 win->alines[i]->line[j].ch = right.vals[ 0 ]; 335 win->alines[i]->line[j].attr = right.attributes; 336 np = win->alines[i]->line[j].nsp; 337 if (np) { 338 while ( np ) { 339 tnp = np->next; 340 free( np ); 341 np = tnp; 342 } 343 win->alines[i]->line[j].nsp = NULL; 344 } 345 if ( j == endx - cw + 1 ) { 346 SET_WCOL( win->alines[i]->line[j], cw ); 347 if ( right.elements > 1 ) { 348 for (k = 1; k < right.elements; k++) { 349 np = (nschar_t *)malloc(sizeof(nschar_t)); 350 if (!np) 351 return ERR; 352 np->ch = right.vals[ k ]; 353 np->next = win->alines[i]->line[j].nsp; 354 win->alines[i]->line[j].nsp 355 = np; 356 } 357 } 358 } else 359 SET_WCOL( win->alines[i]->line[j], 360 endx - cw + 1 - j ); 361 } 362 if ( pcw != 1 ) { 363 #ifdef DEBUG 364 __CTRACE(__CTRACE_INPUT, 365 "wborder_set: clean out partial chars[%d:%d]", 366 endx - cw + pcw, endx - cw ); 367 #endif /* DEBUG */ 368 k = pcw < 0 ? endx -cw + pcw : endx - cw; 369 for ( j = endx - cw; j >= k; j-- ) { 370 win->alines[i]->line[j].ch 371 = (wchar_t)btowc(win->bch); 372 if (_cursesi_copy_nsp(win->bnsp, 373 &win->alines[i]->line[j]) == ERR) 374 return ERR; 375 win->alines[i]->line[j].attr = win->battr; 376 SET_WCOL( win->alines[i]->line[j], 1 ); 377 } 378 } 379 } 380 tlcw = wcwidth( topleft.vals[ 0 ]); 381 if (tlcw < 0) 382 tlcw = 1; 383 blcw = wcwidth( botleft.vals[ 0 ]); 384 if (blcw < 0) 385 blcw = 1; 386 trcw = wcwidth( topright.vals[ 0 ]); 387 if (trcw < 0) 388 trcw = 1; 389 brcw = wcwidth( botright.vals[ 0 ]); 390 if (brcw < 0) 391 brcw = 1; 392 /* upper border */ 393 cw = wcwidth( top.vals[ 0 ]); 394 if (cw < 0) 395 cw = 1; 396 for (i = tlcw; i <= min( endx - cw, endx - trcw ); i += cw ) { 397 for ( j = 0; j < cw; j++ ) { 398 win->alines[ 0 ]->line[i + j].ch = top.vals[ 0 ]; 399 win->alines[ 0 ]->line[i + j].attr = top.attributes; 400 np = win->alines[ 0 ]->line[i + j].nsp; 401 if (np) { 402 while ( np ) { 403 tnp = np->next; 404 free( np ); 405 np = tnp; 406 } 407 win->alines[ 0 ]->line[i + j].nsp = NULL; 408 } 409 if ( j ) 410 SET_WCOL( win->alines[ 0 ]->line[ i + j ], -j ); 411 else { 412 SET_WCOL( win->alines[ 0 ]->line[ i + j ], cw ); 413 if ( top.elements > 1 ) { 414 for ( k = 1; k < top.elements; k++ ) { 415 np = (nschar_t *)malloc(sizeof(nschar_t)); 416 if (!np) 417 return ERR; 418 np->ch = top.vals[ k ]; 419 np->next = win->alines[0]->line[i + j].nsp; 420 win->alines[0]->line[i + j].nsp 421 = np; 422 } 423 } 424 } 425 } 426 } 427 while ( i <= endx - trcw ) { 428 win->alines[0]->line[i].ch = 429 ( wchar_t )btowc(( int ) win->bch ); 430 if (_cursesi_copy_nsp(win->bnsp, 431 &win->alines[0]->line[i]) == ERR) 432 return ERR; 433 win->alines[ 0 ]->line[ i ].attr = win->battr; 434 SET_WCOL( win->alines[ 0 ]->line[ i ], 1 ); 435 i++; 436 } 437 /* lower border */ 438 for (i = blcw; i <= min( endx - cw, endx - brcw ); i += cw ) { 439 for ( j = 0; j < cw; j++ ) { 440 win->alines[ endy ]->line[i + j].ch = bottom.vals[ 0 ]; 441 win->alines[endy]->line[i + j].attr = bottom.attributes; 442 np = win->alines[ endy ]->line[i + j].nsp; 443 if (np) { 444 while ( np ) { 445 tnp = np->next; 446 free( np ); 447 np = tnp; 448 } 449 win->alines[ endy ]->line[i + j].nsp = NULL; 450 } 451 if ( j ) 452 SET_WCOL( win->alines[endy]->line[i + j], -j); 453 else { 454 SET_WCOL( win->alines[endy]->line[i + j], cw ); 455 if ( bottom.elements > 1 ) { 456 for ( k = 1; k < bottom.elements; 457 k++ ) { 458 if ( !( np = ( nschar_t *)malloc( sizeof( nschar_t )))) 459 return ERR; 460 np->ch = bottom.vals[ k ]; 461 np->next = win->alines[endy]->line[i + j].nsp; 462 win->alines[endy]->line[i + j].nsp = np; 463 } 464 } 465 } 466 } 467 } 468 while ( i <= endx - brcw ) { 469 win->alines[endy]->line[i].ch = 470 (wchar_t)btowc((int) win->bch ); 471 if (_cursesi_copy_nsp(win->bnsp, 472 &win->alines[endy]->line[i]) == ERR) 473 return ERR; 474 win->alines[ endy ]->line[ i ].attr = win->battr; 475 SET_WCOL( win->alines[ endy ]->line[ i ], 1 ); 476 i++; 477 } 478 479 /* Corners */ 480 if (!(win->maxx == LINES && win->maxy == COLS && 481 (win->flags & __SCROLLOK) && (win->flags & __SCROLLWIN))) { 482 for ( i = 0; i < tlcw; i++ ) { 483 win->alines[ 0 ]->line[i].ch = topleft.vals[ 0 ]; 484 win->alines[ 0 ]->line[i].attr = topleft.attributes; 485 np = win->alines[ 0 ]->line[i].nsp; 486 if (np) { 487 while ( np ) { 488 tnp = np->next; 489 free( np ); 490 np = tnp; 491 } 492 win->alines[ 0 ]->line[i].nsp = NULL; 493 } 494 if ( i ) 495 SET_WCOL( win->alines[ 0 ]->line[ i ], -i ); 496 else { 497 SET_WCOL( win->alines[ 0 ]->line[ i ], tlcw ); 498 if ( topleft.elements > 1 ) { 499 for ( k = 1; k < topleft.elements; 500 k++ ) { 501 np = (nschar_t *)malloc(sizeof(nschar_t)); 502 if (!np) 503 return ERR; 504 np->ch = topleft.vals[ k ]; 505 np->next = win->alines[ 0 ]->line[i].nsp; 506 win->alines[ 0 ]->line[i].nsp 507 = np; 508 } 509 } 510 } 511 } 512 for ( i = endx - trcw + 1; i <= endx; i++ ) { 513 win->alines[ 0 ]->line[i].ch = topright.vals[ 0 ]; 514 win->alines[ 0 ]->line[i].attr = topright.attributes; 515 np = win->alines[ 0 ]->line[i].nsp; 516 if (np) { 517 while ( np ) { 518 tnp = np->next; 519 free( np ); 520 np = tnp; 521 } 522 win->alines[ 0 ]->line[i].nsp = NULL; 523 } 524 if ( i == endx - trcw + 1 ) { 525 SET_WCOL( win->alines[ 0 ]->line[ i ], trcw ); 526 if ( topright.elements > 1 ) { 527 for ( k = 1; k < topright.elements; 528 k++ ) { 529 np = (nschar_t *)malloc(sizeof(nschar_t)); 530 if (!np) 531 return ERR; 532 np->ch = topright.vals[ k ]; 533 np->next = win->alines[0]->line[i].nsp; 534 win->alines[ 0 ]->line[i].nsp 535 = np; 536 } 537 } 538 } else 539 SET_WCOL( win->alines[ 0 ]->line[ i ], 540 endx - trcw + 1 - i ); 541 } 542 for ( i = 0; i < blcw; i++ ) { 543 win->alines[ endy ]->line[i].ch = botleft.vals[ 0 ]; 544 win->alines[ endy ]->line[i].attr = botleft.attributes; 545 np = win->alines[ endy ]->line[i].nsp; 546 if (np) { 547 while ( np ) { 548 tnp = np->next; 549 free( np ); 550 np = tnp; 551 } 552 win->alines[ endy ]->line[i].nsp = NULL; 553 } 554 if ( i ) 555 SET_WCOL( win->alines[endy]->line[i], -i ); 556 else { 557 SET_WCOL( win->alines[endy]->line[i], blcw ); 558 if ( botleft.elements > 1 ) { 559 for ( k = 1; k < botleft.elements; 560 k++ ) { 561 np = (nschar_t *)malloc(sizeof(nschar_t)); 562 if (!np) 563 return ERR; 564 np->ch = botleft.vals[ k ]; 565 np->next = win->alines[endy]->line[i].nsp; 566 win->alines[endy]->line[i].nsp 567 = np; 568 } 569 } 570 } 571 } 572 for ( i = endx - brcw + 1; i <= endx; i++ ) { 573 win->alines[ endy ]->line[i].ch = botright.vals[ 0 ]; 574 win->alines[ endy ]->line[i].attr = botright.attributes; 575 np = win->alines[ endy ]->line[i].nsp; 576 if (np) { 577 while ( np ) { 578 tnp = np->next; 579 free( np ); 580 np = tnp; 581 } 582 win->alines[ endy ]->line[i].nsp = NULL; 583 } 584 if ( i == endx - brcw + 1 ) { 585 SET_WCOL( win->alines[ endy ]->line[ i ], 586 brcw ); 587 if ( botright.elements > 1 ) { 588 for ( k = 1; k < botright.elements; k++ ) { 589 np = (nschar_t *)malloc(sizeof(nschar_t)); 590 if (!np) 591 return ERR; 592 np->ch = botright.vals[ k ]; 593 np->next = win->alines[endy]->line[i].nsp; 594 win->alines[endy]->line[i].nsp 595 = np; 596 } 597 } 598 } else 599 SET_WCOL( win->alines[ endy ]->line[ i ], 600 endx - brcw + 1 - i ); 601 } 602 } 603 __touchwin(win); 604 return (OK); 605 #endif /* HAVE_WCHAR */ 606 } 607