1 /* $NetBSD: border.c,v 1.18 2017/01/09 21:17:29 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.18 2017/01/09 21:17:29 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->maxy == LINES && win->maxx == 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 left.attributes |= (left.attributes & __COLOR) ? 265 (win->battr & ~__COLOR) : win->battr; 266 right.attributes |= (right.attributes & __COLOR) ? 267 (win->wattr & ~__COLOR) : win->wattr; 268 right.attributes |= (right.attributes & __COLOR) ? 269 (win->battr & ~__COLOR) : win->battr; 270 top.attributes |= (top.attributes & __COLOR) ? 271 (win->wattr & ~__COLOR) : win->wattr; 272 top.attributes |= (top.attributes & __COLOR) ? 273 (win->battr & ~__COLOR) : win->battr; 274 bottom.attributes |= (bottom.attributes & __COLOR) ? 275 (win->wattr & ~__COLOR) : win->wattr; 276 bottom.attributes |= (bottom.attributes & __COLOR) ? 277 (win->battr & ~__COLOR) : win->battr; 278 topleft.attributes |= (topleft.attributes & __COLOR) ? 279 (win->wattr & ~__COLOR) : win->wattr; 280 topleft.attributes |= (topleft.attributes & __COLOR) ? 281 (win->battr & ~__COLOR) : win->battr; 282 topright.attributes |= (topright.attributes & __COLOR) ? 283 (win->wattr & ~__COLOR) : win->wattr; 284 topright.attributes |= (topright.attributes & __COLOR) ? 285 (win->battr & ~__COLOR) : win->battr; 286 botleft.attributes |= (botleft.attributes & __COLOR) ? 287 (win->wattr & ~__COLOR) : win->wattr; 288 botleft.attributes |= (botleft.attributes & __COLOR) ? 289 (win->battr & ~__COLOR) : win->battr; 290 botright.attributes |= (botright.attributes & __COLOR) ? 291 (win->wattr & ~__COLOR) : win->wattr; 292 botright.attributes |= (botright.attributes & __COLOR) ? 293 (win->battr & ~__COLOR) : win->battr; 294 295 endx = win->maxx - 1; 296 endy = win->maxy - 1; 297 298 /* Sides */ 299 for (i = 1; i < endy; i++) { 300 /* left border */ 301 cw = wcwidth(left.vals[0]); 302 if (cw < 0) 303 cw = 1; 304 for ( j = 0; j < cw; j++ ) { 305 win->alines[i]->line[j].ch = left.vals[0]; 306 win->alines[i]->line[j].attr = left.attributes; 307 np = win->alines[i]->line[j].nsp; 308 if (np) { 309 while (np) { 310 tnp = np->next; 311 free(np); 312 np = tnp; 313 } 314 win->alines[i]->line[j].nsp = NULL; 315 } 316 if (j) 317 SET_WCOL(win->alines[i]->line[j], -j); 318 else { 319 SET_WCOL(win->alines[i]->line[j], cw); 320 if (left.elements > 1) { 321 for (k = 1; k < left.elements; k++) { 322 np = malloc(sizeof(nschar_t)); 323 if (!np) 324 return ERR; 325 np->ch = left.vals[ k ]; 326 np->next = win->alines[i]->line[j].nsp; 327 win->alines[i]->line[j].nsp 328 = np; 329 } 330 } 331 } 332 } 333 for (j = cw; WCOL(win->alines[i]->line[j]) < 0; j++) { 334 #ifdef DEBUG 335 __CTRACE(__CTRACE_INPUT, 336 "wborder_set: clean out partial char[%d]", j); 337 #endif /* DEBUG */ 338 win->alines[i]->line[j].ch = ( wchar_t )btowc(win->bch); 339 if (_cursesi_copy_nsp(win->bnsp, 340 &win->alines[i]->line[j]) == ERR) 341 return ERR; 342 SET_WCOL(win->alines[i]->line[j], 1); 343 } 344 /* right border */ 345 cw = wcwidth(right.vals[0]); 346 if (cw < 0) 347 cw = 1; 348 pcw = WCOL( win->alines[i]->line[endx - cw]); 349 for ( j = endx - cw + 1; j <= endx; j++ ) { 350 win->alines[i]->line[j].ch = right.vals[0]; 351 win->alines[i]->line[j].attr = right.attributes; 352 np = win->alines[i]->line[j].nsp; 353 if (np) { 354 while (np) { 355 tnp = np->next; 356 free(np); 357 np = tnp; 358 } 359 win->alines[i]->line[j].nsp = NULL; 360 } 361 if (j == endx - cw + 1) { 362 SET_WCOL(win->alines[i]->line[j], cw); 363 if (right.elements > 1) { 364 for (k = 1; k < right.elements; k++) { 365 np = malloc(sizeof(nschar_t)); 366 if (!np) 367 return ERR; 368 np->ch = right.vals[ k ]; 369 np->next = win->alines[i]->line[j].nsp; 370 win->alines[i]->line[j].nsp 371 = np; 372 } 373 } 374 } else 375 SET_WCOL(win->alines[i]->line[j], 376 endx - cw + 1 - j); 377 } 378 if (pcw != 1) { 379 #ifdef DEBUG 380 __CTRACE(__CTRACE_INPUT, 381 "wborder_set: clean out partial chars[%d:%d]", 382 endx - cw + pcw, endx - cw ); 383 #endif /* DEBUG */ 384 k = pcw < 0 ? endx -cw + pcw : endx - cw; 385 for (j = endx - cw; j >= k; j--) { 386 win->alines[i]->line[j].ch 387 = (wchar_t)btowc(win->bch); 388 if (_cursesi_copy_nsp(win->bnsp, 389 &win->alines[i]->line[j]) == ERR) 390 return ERR; 391 win->alines[i]->line[j].attr = win->battr; 392 SET_WCOL(win->alines[i]->line[j], 1); 393 } 394 } 395 } 396 tlcw = wcwidth(topleft.vals[0]); 397 if (tlcw < 0) 398 tlcw = 1; 399 blcw = wcwidth(botleft.vals[0]); 400 if (blcw < 0) 401 blcw = 1; 402 trcw = wcwidth(topright.vals[0]); 403 if (trcw < 0) 404 trcw = 1; 405 brcw = wcwidth(botright.vals[0]); 406 if (brcw < 0) 407 brcw = 1; 408 /* upper border */ 409 cw = wcwidth(top.vals[0]); 410 if (cw < 0) 411 cw = 1; 412 for (i = tlcw; i <= min( endx - cw, endx - trcw); i += cw) { 413 for (j = 0; j < cw; j++) { 414 win->alines[0]->line[i + j].ch = top.vals[0]; 415 win->alines[0]->line[i + j].attr = top.attributes; 416 np = win->alines[0]->line[i + j].nsp; 417 if (np) { 418 while (np) { 419 tnp = np->next; 420 free(np); 421 np = tnp; 422 } 423 win->alines[0]->line[i + j].nsp = NULL; 424 } 425 if (j) 426 SET_WCOL(win->alines[ 0 ]->line[ i + j ], -j); 427 else { 428 SET_WCOL(win->alines[ 0 ]->line[ i + j ], cw); 429 if ( top.elements > 1 ) { 430 for (k = 1; k < top.elements; k++) { 431 np = malloc(sizeof(nschar_t)); 432 if (!np) 433 return ERR; 434 np->ch = top.vals[k]; 435 np->next = win->alines[0]->line[i + j].nsp; 436 win->alines[0]->line[i + j].nsp 437 = np; 438 } 439 } 440 } 441 } 442 } 443 while (i <= endx - trcw) { 444 win->alines[0]->line[i].ch = 445 (wchar_t)btowc((int) win->bch); 446 if (_cursesi_copy_nsp(win->bnsp, 447 &win->alines[0]->line[i]) == ERR) 448 return ERR; 449 win->alines[0]->line[i].attr = win->battr; 450 SET_WCOL(win->alines[0]->line[i], 1); 451 i++; 452 } 453 /* lower border */ 454 for (i = blcw; i <= min( endx - cw, endx - brcw); i += cw) { 455 for (j = 0; j < cw; j++) { 456 win->alines[endy]->line[i + j].ch = bottom.vals[0]; 457 win->alines[endy]->line[i + j].attr = bottom.attributes; 458 np = win->alines[endy]->line[i + j].nsp; 459 if (np) { 460 while (np) { 461 tnp = np->next; 462 free(np); 463 np = tnp; 464 } 465 win->alines[endy]->line[i + j].nsp = NULL; 466 } 467 if (j) 468 SET_WCOL(win->alines[endy]->line[i + j], -j); 469 else { 470 SET_WCOL(win->alines[endy]->line[i + j], cw); 471 if (bottom.elements > 1) { 472 for (k = 1; k < bottom.elements; k++) { 473 np = malloc(sizeof(nschar_t)); 474 if (!np) 475 return ERR; 476 np->ch = bottom.vals[ k ]; 477 np->next = win->alines[endy]->line[i + j].nsp; 478 win->alines[endy]->line[i + j].nsp = np; 479 } 480 } 481 } 482 } 483 } 484 while (i <= endx - brcw) { 485 win->alines[endy]->line[i].ch = (wchar_t)btowc((int) win->bch ); 486 if (_cursesi_copy_nsp(win->bnsp, 487 &win->alines[endy]->line[i]) == ERR) 488 return ERR; 489 win->alines[endy]->line[i].attr = win->battr; 490 SET_WCOL(win->alines[endy]->line[ i ], 1); 491 i++; 492 } 493 494 /* Corners */ 495 if (!(win->maxy == LINES && win->maxx == COLS && 496 (win->flags & __SCROLLOK) && (win->flags & __SCROLLWIN))) { 497 for (i = 0; i < tlcw; i++) { 498 win->alines[0]->line[i].ch = topleft.vals[0]; 499 win->alines[0]->line[i].attr = topleft.attributes; 500 np = win->alines[0]->line[i].nsp; 501 if (np) { 502 while (np) { 503 tnp = np->next; 504 free(np); 505 np = tnp; 506 } 507 win->alines[0]->line[i].nsp = NULL; 508 } 509 if (i) 510 SET_WCOL(win->alines[0]->line[i], -i); 511 else { 512 SET_WCOL(win->alines[0]->line[i], tlcw); 513 if (topleft.elements > 1) { 514 for (k = 1; k < topleft.elements; k++) 515 { 516 np = malloc(sizeof(nschar_t)); 517 if (!np) 518 return ERR; 519 np->ch = topleft.vals[k]; 520 np->next = win->alines[0]->line[i].nsp; 521 win->alines[0]->line[i].nsp = np; 522 } 523 } 524 } 525 } 526 for (i = endx - trcw + 1; i <= endx; i++) { 527 win->alines[0]->line[i].ch = topright.vals[0]; 528 win->alines[0]->line[i].attr = topright.attributes; 529 np = win->alines[0]->line[i].nsp; 530 if (np) { 531 while (np) { 532 tnp = np->next; 533 free(np); 534 np = tnp; 535 } 536 win->alines[0]->line[i].nsp = NULL; 537 } 538 if (i == endx - trcw + 1) { 539 SET_WCOL(win->alines[0]->line[i], trcw); 540 if (topright.elements > 1) { 541 for (k = 1; k < topright.elements;k ++) 542 { 543 np = malloc(sizeof(nschar_t)); 544 if (!np) 545 return ERR; 546 np->ch = topright.vals[k]; 547 np->next = win->alines[0]->line[i].nsp; 548 win->alines[ 0 ]->line[i].nsp = np; 549 } 550 } 551 } else 552 SET_WCOL(win->alines[0]->line[i], 553 endx - trcw + 1 - i); 554 } 555 for (i = 0; i < blcw; i++) { 556 win->alines[endy]->line[i].ch = botleft.vals[0]; 557 win->alines[endy]->line[i].attr = botleft.attributes; 558 np = win->alines[ endy ]->line[i].nsp; 559 if (np) { 560 while (np) { 561 tnp = np->next; 562 free(np); 563 np = tnp; 564 } 565 win->alines[endy]->line[i].nsp = NULL; 566 } 567 if (i) 568 SET_WCOL(win->alines[endy]->line[i], -i); 569 else { 570 SET_WCOL(win->alines[endy]->line[i], blcw); 571 if (botleft.elements > 1) { 572 for (k = 1; k < botleft.elements; k++) { 573 np = malloc(sizeof(nschar_t)); 574 if (!np) 575 return ERR; 576 np->ch = botleft.vals[ k ]; 577 np->next = win->alines[endy]->line[i].nsp; 578 win->alines[endy]->line[i].nsp = np; 579 } 580 } 581 } 582 } 583 for (i = endx - brcw + 1; i <= endx; i++) { 584 win->alines[endy]->line[i].ch = botright.vals[0]; 585 win->alines[endy]->line[i].attr = botright.attributes; 586 np = win->alines[endy]->line[i].nsp; 587 if (np) { 588 while (np) { 589 tnp = np->next; 590 free(np); 591 np = tnp; 592 } 593 win->alines[endy]->line[i].nsp = NULL; 594 } 595 if (i == endx - brcw + 1) { 596 SET_WCOL(win->alines[endy]->line[i], brcw); 597 if (botright.elements > 1) { 598 for (k = 1; k < botright.elements; k++){ 599 np = malloc(sizeof(nschar_t)); 600 if (!np) 601 return ERR; 602 np->ch = botright.vals[k]; 603 np->next = win->alines[endy]->line[i].nsp; 604 win->alines[endy]->line[i].nsp = np; 605 } 606 } 607 } else 608 SET_WCOL(win->alines[endy]->line[i], 609 endx - brcw + 1 - i); 610 } 611 } 612 __touchwin(win); 613 return OK; 614 #endif /* HAVE_WCHAR */ 615 } 616