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