1 /* $NetBSD: border.c,v 1.21 2021/10/19 06:41:03 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.21 2021/10/19 06:41:03 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); 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 SET_WCOL(win->alines[i]->line[j], -j); 316 else { 317 SET_WCOL(win->alines[i]->line[j], 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; WCOL(win->alines[i]->line[j]) < 0; j++) { 332 __CTRACE(__CTRACE_INPUT, 333 "wborder_set: clean out partial char[%d]", j); 334 win->alines[i]->line[j].ch = ( wchar_t )btowc(win->bch); 335 if (_cursesi_copy_nsp(win->bnsp, 336 &win->alines[i]->line[j]) == ERR) 337 return ERR; 338 SET_WCOL(win->alines[i]->line[j], 1); 339 } 340 /* right border */ 341 cw = wcwidth(right.vals[0]); 342 if (cw < 0) 343 cw = 1; 344 pcw = WCOL( win->alines[i]->line[endx - cw]); 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 SET_WCOL(win->alines[i]->line[j], 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 SET_WCOL(win->alines[i]->line[j], 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 381 = (wchar_t)btowc(win->bch); 382 if (_cursesi_copy_nsp(win->bnsp, 383 &win->alines[i]->line[j]) == ERR) 384 return ERR; 385 win->alines[i]->line[j].attr = win->battr; 386 SET_WCOL(win->alines[i]->line[j], 1); 387 } 388 } 389 } 390 tlcw = wcwidth(topleft.vals[0]); 391 if (tlcw < 0) 392 tlcw = 1; 393 blcw = wcwidth(botleft.vals[0]); 394 if (blcw < 0) 395 blcw = 1; 396 trcw = wcwidth(topright.vals[0]); 397 if (trcw < 0) 398 trcw = 1; 399 brcw = wcwidth(botright.vals[0]); 400 if (brcw < 0) 401 brcw = 1; 402 /* upper border */ 403 cw = wcwidth(top.vals[0]); 404 if (cw < 0) 405 cw = 1; 406 for (i = tlcw; i <= min( endx - cw, endx - trcw); i += cw) { 407 for (j = 0; j < cw; j++) { 408 win->alines[0]->line[i + j].ch = top.vals[0]; 409 win->alines[0]->line[i + j].attr = top.attributes; 410 np = win->alines[0]->line[i + j].nsp; 411 if (np) { 412 while (np) { 413 tnp = np->next; 414 free(np); 415 np = tnp; 416 } 417 win->alines[0]->line[i + j].nsp = NULL; 418 } 419 if (j) 420 SET_WCOL(win->alines[ 0 ]->line[ i + j ], -j); 421 else { 422 SET_WCOL(win->alines[ 0 ]->line[ i + j ], cw); 423 if ( top.elements > 1 ) { 424 for (k = 1; k < top.elements; k++) { 425 np = malloc(sizeof(nschar_t)); 426 if (!np) 427 return ERR; 428 np->ch = top.vals[k]; 429 np->next = win->alines[0]->line[i + j].nsp; 430 win->alines[0]->line[i + j].nsp 431 = np; 432 } 433 } 434 } 435 } 436 } 437 while (i <= endx - trcw) { 438 win->alines[0]->line[i].ch = 439 (wchar_t)btowc((int) win->bch); 440 if (_cursesi_copy_nsp(win->bnsp, 441 &win->alines[0]->line[i]) == ERR) 442 return ERR; 443 win->alines[0]->line[i].attr = win->battr; 444 SET_WCOL(win->alines[0]->line[i], 1); 445 i++; 446 } 447 /* lower border */ 448 for (i = blcw; i <= min( endx - cw, endx - brcw); i += cw) { 449 for (j = 0; j < cw; j++) { 450 win->alines[endy]->line[i + j].ch = bottom.vals[0]; 451 win->alines[endy]->line[i + j].attr = bottom.attributes; 452 np = win->alines[endy]->line[i + j].nsp; 453 if (np) { 454 while (np) { 455 tnp = np->next; 456 free(np); 457 np = tnp; 458 } 459 win->alines[endy]->line[i + j].nsp = NULL; 460 } 461 if (j) 462 SET_WCOL(win->alines[endy]->line[i + j], -j); 463 else { 464 SET_WCOL(win->alines[endy]->line[i + j], cw); 465 if (bottom.elements > 1) { 466 for (k = 1; k < bottom.elements; k++) { 467 np = malloc(sizeof(nschar_t)); 468 if (!np) 469 return ERR; 470 np->ch = bottom.vals[ k ]; 471 np->next = win->alines[endy]->line[i + j].nsp; 472 win->alines[endy]->line[i + j].nsp = np; 473 } 474 } 475 } 476 } 477 } 478 while (i <= endx - brcw) { 479 win->alines[endy]->line[i].ch = (wchar_t)btowc((int) win->bch ); 480 if (_cursesi_copy_nsp(win->bnsp, 481 &win->alines[endy]->line[i]) == ERR) 482 return ERR; 483 win->alines[endy]->line[i].attr = win->battr; 484 SET_WCOL(win->alines[endy]->line[ i ], 1); 485 i++; 486 } 487 488 /* Corners */ 489 if (!(win->maxy == LINES && win->maxx == COLS && 490 (win->flags & __SCROLLOK) && (win->flags & __SCROLLWIN))) { 491 for (i = 0; i < tlcw; i++) { 492 win->alines[0]->line[i].ch = topleft.vals[0]; 493 win->alines[0]->line[i].attr = topleft.attributes; 494 np = win->alines[0]->line[i].nsp; 495 if (np) { 496 while (np) { 497 tnp = np->next; 498 free(np); 499 np = tnp; 500 } 501 win->alines[0]->line[i].nsp = NULL; 502 } 503 if (i) 504 SET_WCOL(win->alines[0]->line[i], -i); 505 else { 506 SET_WCOL(win->alines[0]->line[i], tlcw); 507 if (topleft.elements > 1) { 508 for (k = 1; k < topleft.elements; k++) 509 { 510 np = malloc(sizeof(nschar_t)); 511 if (!np) 512 return ERR; 513 np->ch = topleft.vals[k]; 514 np->next = win->alines[0]->line[i].nsp; 515 win->alines[0]->line[i].nsp = np; 516 } 517 } 518 } 519 } 520 for (i = endx - trcw + 1; i <= endx; i++) { 521 win->alines[0]->line[i].ch = topright.vals[0]; 522 win->alines[0]->line[i].attr = topright.attributes; 523 np = win->alines[0]->line[i].nsp; 524 if (np) { 525 while (np) { 526 tnp = np->next; 527 free(np); 528 np = tnp; 529 } 530 win->alines[0]->line[i].nsp = NULL; 531 } 532 if (i == endx - trcw + 1) { 533 SET_WCOL(win->alines[0]->line[i], trcw); 534 if (topright.elements > 1) { 535 for (k = 1; k < topright.elements;k ++) 536 { 537 np = malloc(sizeof(nschar_t)); 538 if (!np) 539 return ERR; 540 np->ch = topright.vals[k]; 541 np->next = win->alines[0]->line[i].nsp; 542 win->alines[ 0 ]->line[i].nsp = np; 543 } 544 } 545 } else 546 SET_WCOL(win->alines[0]->line[i], 547 endx - trcw + 1 - i); 548 } 549 for (i = 0; i < blcw; i++) { 550 win->alines[endy]->line[i].ch = botleft.vals[0]; 551 win->alines[endy]->line[i].attr = botleft.attributes; 552 np = win->alines[ endy ]->line[i].nsp; 553 if (np) { 554 while (np) { 555 tnp = np->next; 556 free(np); 557 np = tnp; 558 } 559 win->alines[endy]->line[i].nsp = NULL; 560 } 561 if (i) 562 SET_WCOL(win->alines[endy]->line[i], -i); 563 else { 564 SET_WCOL(win->alines[endy]->line[i], blcw); 565 if (botleft.elements > 1) { 566 for (k = 1; k < botleft.elements; k++) { 567 np = malloc(sizeof(nschar_t)); 568 if (!np) 569 return ERR; 570 np->ch = botleft.vals[ k ]; 571 np->next = win->alines[endy]->line[i].nsp; 572 win->alines[endy]->line[i].nsp = np; 573 } 574 } 575 } 576 } 577 for (i = endx - brcw + 1; i <= endx; i++) { 578 win->alines[endy]->line[i].ch = botright.vals[0]; 579 win->alines[endy]->line[i].attr = botright.attributes; 580 np = win->alines[endy]->line[i].nsp; 581 if (np) { 582 while (np) { 583 tnp = np->next; 584 free(np); 585 np = tnp; 586 } 587 win->alines[endy]->line[i].nsp = NULL; 588 } 589 if (i == endx - brcw + 1) { 590 SET_WCOL(win->alines[endy]->line[i], brcw); 591 if (botright.elements > 1) { 592 for (k = 1; k < botright.elements; k++){ 593 np = malloc(sizeof(nschar_t)); 594 if (!np) 595 return ERR; 596 np->ch = botright.vals[k]; 597 np->next = win->alines[endy]->line[i].nsp; 598 win->alines[endy]->line[i].nsp = np; 599 } 600 } 601 } else 602 SET_WCOL(win->alines[endy]->line[i], 603 endx - brcw + 1 - i); 604 } 605 } 606 __touchwin(win); 607 return OK; 608 #endif /* HAVE_WCHAR */ 609 } 610