border.c revision 1.25 1 /* $NetBSD: border.c,v 1.25 2024/12/23 02:58: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.25 2024/12/23 02:58: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 (__predict_false(win == NULL))
74 return;
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