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