/* * wbkgd -- * Set new background and new background attributes. */ int wbkgd(WINDOW *win, chtype ch) { int y, x; #ifdef DEBUG __CTRACE(__CTRACE_ATTR, "wbkgd: (%p), '%s', %08x\n", win, unctrl(ch & +__CHARTEXT), ch & __ATTRIBUTES); #endif /* Background attributes (check colour). */ if (__using_color && !(ch & __COLOR)) ch |= __default_color; win->battr = (attr_t) ch & __ATTRIBUTES; wbkgdset(win, ch); for (y = 0; y < win->maxy; y++) for (x = 0; x < win->maxx; x++) { /* Copy character if space */ if (ch & A_CHARTEXT && win->alines[y]->line[x].ch == ' ') win->alines[y]->line[x].ch = ch & __CHARTEXT; /* Merge attributes */ if (win->alines[y]->line[x].attr & __ALTCHARSET) win->alines[y]->line[x].attr = (ch & __ATTRIBUTES) | __ALTCHARSET; else win->alines[y]->line[x].attr = ch & __ATTRIBUTES; #ifdef HAVE_WCHAR SET_WCOL(win->alines[y]->line[x], 1); #endif } __touchwin(win); return(OK); }
/* * wbkgd -- * Set new background and new background attributes. */ int wbkgd(WINDOW *win, chtype ch) { int y, x; /* Background attributes (check colour). */ if (__using_color && !(ch & __COLOR)) ch |= __default_color; win->battr = (attr_t) ch & __ATTRIBUTES; wbkgdset(win, ch); for (y = 0; y < win->maxy; y++) for (x = 0; x < win->maxx; x++) { /* Copy character if space */ if (ch & A_CHARTEXT && win->alines[y]->line[x].ch == ' ') win->alines[y]->line[x].ch = ch & __CHARTEXT; /* Merge attributes */ if (win->alines[y]->line[x].attr & __ALTCHARSET) win->alines[y]->line[x].attr = (ch & __ATTRIBUTES) | __ALTCHARSET; else win->alines[y]->line[x].attr = ch & __ATTRIBUTES; SET_WCOL(win->alines[y]->line[x], 1); } __touchwin(win); return(OK); }
WINDOW * __newwin(SCREEN *screen, int nlines, int ncols, int by, int bx, int ispad) { WINDOW *win; __LINE *lp; int i, j; int maxy, maxx; __LDATA *sp; if (by < 0 || bx < 0) return (NULL); maxy = nlines > 0 ? nlines : LINES - by + nlines; maxx = ncols > 0 ? ncols : COLS - bx + ncols; if ((win = __makenew(screen, maxy, maxx, by, bx, 0, ispad)) == NULL) return (NULL); win->bch = ' '; if (__using_color) win->battr = __default_color; else win->battr = 0; win->nextp = win; win->ch_off = 0; win->orig = NULL; win->reqy = nlines; win->reqx = ncols; #ifdef DEBUG __CTRACE(__CTRACE_WINDOW, "newwin: win->ch_off = %d\n", win->ch_off); #endif for (i = 0; i < maxy; i++) { lp = win->alines[i]; if (ispad) lp->flags = __ISDIRTY; else lp->flags = 0; for (sp = lp->line, j = 0; j < maxx; j++, sp++) { sp->attr = 0; #ifndef HAVE_WCHAR sp->ch = win->bch; #else sp->ch = ( wchar_t )btowc(( int ) win->bch ); sp->nsp = NULL; SET_WCOL( *sp, 1 ); #endif /* HAVE_WCHAR */ } lp->hash = __hash((char *)(void *)lp->line, (size_t) (ncols * __LDATASIZE)); } return (win); }
/* * werase -- * Erases everything on the window. */ int werase(WINDOW *win) { int y; __LDATA *sp, *end, *start; attr_t attr; #ifdef DEBUG __CTRACE(__CTRACE_ERASE, "werase: (%p)\n", win); #endif if (win != curscr) attr = win->battr & __ATTRIBUTES; else attr = 0; for (y = 0; y < win->maxy; y++) { start = win->alines[y]->line; end = &start[win->maxx]; for (sp = start; sp < end; sp++) #ifndef HAVE_WCHAR if (sp->ch != win->bch || sp->attr != 0) { #else if (sp->ch != ( wchar_t )btowc(( int ) win->bch ) || (sp->attr & WA_ATTRIBUTES) != 0 || sp->nsp) { #endif /* HAVE_WCHAR */ if (sp->attr & __ALTCHARSET) sp->attr = attr | __ALTCHARSET; else sp->attr = attr; #ifdef HAVE_WCHAR sp->ch = ( wchar_t )btowc(( int ) win->bch); if (_cursesi_copy_nsp(win->bnsp, sp) == ERR) return ERR; SET_WCOL( *sp, 1 ); #else sp->ch = win->bch; #endif /* HAVE_WCHAR */ } } /* * Mark the whole window as changed in case we have overlapping * windows - this will result in the (intended) clearing of the * screen over the area covered by the window. */ __touchwin(win); wmove(win, 0, 0); return (OK); }
/* * wdelch -- * Do a delete-char on the line, leaving (cury, curx) unchanged. */ int wdelch(WINDOW *win) { __LDATA *end, *temp1, *temp2; int cw, sx; nschar_t *np, *tnp; end = &win->alines[win->cury]->line[win->maxx - 1]; sx = win->curx; temp1 = &win->alines[win->cury]->line[win->curx]; cw = WCOL( *temp1 ); if ( cw < 0 ) { temp1 += cw; sx += cw; cw = WCOL( *temp1 ); } np = temp1->nsp; if (np) { while ( np ) { tnp = np->next; free( np ); np = tnp; } temp1->nsp = NULL; } if ( sx + cw < win->maxx ) { temp2 = temp1 + cw; while ( temp1 < end - ( cw - 1 )) { ( void )memcpy( temp1, temp2, sizeof( __LDATA )); temp1++, temp2++; } } while ( temp1 <= end ) { temp1->ch = ( wchar_t )btowc(( int ) win->bch ); temp1->attr = 0; if (_cursesi_copy_nsp(win->bnsp, temp1) == ERR) return ERR; SET_WCOL(*temp1, 1); temp1++; } __touchline(win, (int) win->cury, sx, (int) win->maxx - 1); return (OK); }
/* * winsnstr -- * Do an insert-n-string on the line, leaving (cury, curx) unchanged. * Performs wrapping. */ int winsnstr(WINDOW *win, const char *str, int n) { __LDATA *end, *temp1, *temp2; const char *scp; int len, x; __LINE *lnp; #ifdef HAVE_WCHAR nschar_t *np, *tnp; #endif /* HAVE_WCHAR */ /* find string length */ if ( n > 0 ) for ( scp = str, len = 0; n-- && *scp++; ++len ); else for ( scp = str, len = 0; *scp++; ++len ); #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "winsnstr: len = %d\n", len); #endif /* DEBUG */ /* move string */ end = &win->alines[win->cury]->line[win->curx]; if ( len < win->maxx - win->curx ) { #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "winsnstr: shift %d cells\n", len); #endif /* DEBUG */ temp1 = &win->alines[win->cury]->line[win->maxx - 1]; temp2 = temp1 - len; while (temp2 >= end) { #ifdef HAVE_WCHAR np = temp1->nsp; if (np){ while ( np ) { tnp = np->next; free( np ); np = tnp; } temp1->nsp = NULL; } #endif /* HAVE_WCHAR */ (void) memcpy(temp1, temp2, sizeof(__LDATA)); temp1--, temp2--; } } for ( scp = str, temp1 = end, x = win->curx; *scp && x < len + win->curx && x < win->maxx; scp++, temp1++, x++ ) { temp1->ch = (wchar_t)*scp & __CHARTEXT; temp1->attr = win->wattr; #ifdef HAVE_WCHAR SET_WCOL( *temp1, 1 ); #endif /* HAVE_WCHAR */ } #ifdef DEBUG { int i; for ( i = win->curx; i < win->curx + len; i++ ) { __CTRACE(__CTRACE_INPUT, "winsnstr: (%d,%d)=('%c',%x)\n", win->cury, i, win->alines[win->cury]->line[i].ch, win->alines[win->cury]->line[i].attr); } } #endif /* DEBUG */ lnp = win->alines[ win->cury ]; lnp->flags |= __ISDIRTY; if ( win->ch_off < *lnp->firstchp ) *lnp->firstchp = win->ch_off; if ( win->ch_off + win->maxx - 1 > *lnp->lastchp ) *lnp->lastchp = win->ch_off + win->maxx - 1; __touchline(win, (int)win->cury, (int)win->curx, (int)win->maxx - 1); return OK; }
/* * _cursesi_addwchar - * Internal function to add a wide character and update the row * and column positions. */ int _cursesi_addwchar(WINDOW *win, __LINE **lnp, int *y, int *x, const cchar_t *wch) { #ifndef HAVE_WCHAR return (ERR); #else int sx = 0, ex = 0, cw = 0, i = 0, newx = 0; __LDATA *lp = &win->alines[*y]->line[*x], *tp = NULL; nschar_t *np = NULL; cchar_t cc; attr_t attributes; /* special characters handling */ switch (wch->vals[0]) { case L'\b': if (--*x < 0) *x = 0; win->curx = *x; return OK; case L'\r': *x = 0; return OK; case L'\n': wclrtoeol(win); PSYNCH_IN; *x = 0; (*lnp)->flags &= ~__ISPASTEOL; if (*y == win->scr_b) { if (!(win->flags & __SCROLLOK)) return ERR; PSYNCH_OUT; scroll(win); PSYNCH_IN; } else { (*y)++; } PSYNCH_OUT; return OK; case L'\t': cc.vals[0] = L' '; cc.elements = 1; cc.attributes = win->wattr; for (i = 0; i < 8 - (*x % 8); i++) { if (wadd_wch(win, &cc) == ERR) return ERR; } return OK; } /* check for non-spacing character */ if (!wcwidth(wch->vals[0])) { #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: char '%c' is non-spacing\n", wch->vals[0]); #endif /* DEBUG */ cw = WCOL(*lp); if (cw < 0) { lp += cw; *x += cw; } for (i = 0; i < wch->elements; i++) { if (!(np = (nschar_t *) malloc(sizeof(nschar_t)))) return ERR;; np->ch = wch->vals[i]; np->next = lp->nsp; lp->nsp = np; } (*lnp)->flags |= __ISDIRTY; newx = *x + win->ch_off; if (newx < *(*lnp)->firstchp) *(*lnp)->firstchp = newx; if (newx > *(*lnp)->lastchp) *(*lnp)->lastchp = newx; __touchline(win, *y, *x, *x); return OK; } /* check for new line first */ if ((*lnp)->flags & __ISPASTEOL) { *x = 0; (*lnp)->flags &= ~__ISPASTEOL; if (*y == win->scr_b) { if (!(win->flags & __SCROLLOK)) return ERR; PSYNCH_OUT; scroll(win); PSYNCH_IN; } else { (*y)++; } (*lnp) = win->alines[*y]; lp = &win->alines[*y]->line[*x]; } /* clear out the current character */ cw = WCOL(*lp); if (cw >= 0) { sx = *x; } else { for (sx = *x - 1; sx >= max(*x + cw, 0); sx--) { #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: clear current char (%d,%d)\n", *y, sx); #endif /* DEBUG */ tp = &win->alines[*y]->line[sx]; tp->ch = (wchar_t) btowc((int) win->bch); if (_cursesi_copy_nsp(win->bnsp, tp) == ERR) return ERR; tp->attr = win->battr; SET_WCOL(*tp, 1); } sx = *x + cw; (*lnp)->flags |= __ISDIRTY; newx = sx + win->ch_off; if (newx < *(*lnp)->firstchp) *(*lnp)->firstchp = newx; } /* check for enough space before the end of line */ cw = wcwidth(wch->vals[0]); if (cw < 0) cw = 1; if (cw > win->maxx - *x) { #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: clear EOL (%d,%d)\n", *y, *x); #endif /* DEBUG */ (*lnp)->flags |= __ISDIRTY; newx = *x + win->ch_off; if (newx < *(*lnp)->firstchp) *(*lnp)->firstchp = newx; for (tp = lp; *x < win->maxx; tp++, (*x)++) { tp->ch = (wchar_t) btowc((int) win->bch); if (_cursesi_copy_nsp(win->bnsp, tp) == ERR) return ERR; tp->attr = win->battr; SET_WCOL(*tp, 1); } newx = win->maxx - 1 + win->ch_off; if (newx > *(*lnp)->lastchp) *(*lnp)->lastchp = newx; __touchline(win, *y, sx, (int) win->maxx - 1); sx = *x = 0; if (*y == win->scr_b) { if (!(win->flags & __SCROLLOK)) return ERR; PSYNCH_OUT; scroll(win); PSYNCH_IN; } else { (*y)++; } lp = &win->alines[*y]->line[0]; (*lnp) = win->alines[*y]; } win->cury = *y; /* add spacing character */ #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: add character (%d,%d) 0x%x\n", *y, *x, wch->vals[0]); #endif /* DEBUG */ (*lnp)->flags |= __ISDIRTY; newx = *x + win->ch_off; if (newx < *(*lnp)->firstchp) *(*lnp)->firstchp = newx; if (lp->nsp) { __cursesi_free_nsp(lp->nsp); lp->nsp = NULL; } lp->ch = wch->vals[0]; attributes = (win->wattr | wch->attributes) & (WA_ATTRIBUTES & ~__COLOR); if (wch->attributes & __COLOR) attributes |= wch->attributes & __COLOR; else if (win->wattr & __COLOR) attributes |= win->wattr & __COLOR; if (attributes & __COLOR) lp->attr = attributes | (win->battr & ~__COLOR); else lp->attr = attributes | win->battr; SET_WCOL(*lp, cw); #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: add spacing char 0x%x, attr 0x%x\n", lp->ch, lp->attr); #endif /* DEBUG */ if (wch->elements > 1) { for (i = 1; i < wch->elements; i++) { np = (nschar_t *)malloc(sizeof(nschar_t)); if (!np) return ERR;; np->ch = wch->vals[i]; np->next = lp->nsp; #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: add non-spacing char 0x%x\n", np->ch); #endif /* DEBUG */ lp->nsp = np; } } #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: non-spacing list header: %p\n", lp->nsp); __CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: add rest columns (%d:%d)\n", sx + 1, sx + cw - 1); #endif /* DEBUG */ for (tp = lp + 1, *x = sx + 1; *x - sx <= cw - 1; tp++, (*x)++) { if (tp->nsp) { __cursesi_free_nsp(tp->nsp); tp->nsp = NULL; } tp->ch = wch->vals[0]; tp->attr = lp->attr & WA_ATTRIBUTES; /* Mark as "continuation" cell */ tp->attr |= __WCWIDTH; } if (*x == win->maxx) { (*lnp)->flags |= __ISPASTEOL; newx = win->maxx - 1 + win->ch_off; if (newx > *(*lnp)->lastchp) *(*lnp)->lastchp = newx; __touchline(win, *y, sx, (int) win->maxx - 1); win->curx = sx; } else { win->curx = *x; /* clear the remining of the current characer */ if (*x && *x < win->maxx) { ex = sx + cw; tp = &win->alines[*y]->line[ex]; while (ex < win->maxx && WCOL(*tp) < 0) { #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: clear " "remaining of current char (%d,%d)nn", *y, ex); #endif /* DEBUG */ tp->ch = (wchar_t) btowc((int) win->bch); if (_cursesi_copy_nsp(win->bnsp, tp) == ERR) return ERR; tp->attr = win->battr; SET_WCOL(*tp, 1); tp++, ex++; } newx = ex - 1 + win->ch_off; if (newx > *(*lnp)->lastchp) *(*lnp)->lastchp = newx; __touchline(win, *y, sx, ex - 1); } } #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "add_wch: %d : 0x%x\n", lp->ch, lp->attr); #endif /* DEBUG */ return OK; #endif }
int wborder_set(WINDOW *win, const cchar_t *ls, const cchar_t *rs, const cchar_t *ts, const cchar_t *bs, const cchar_t *tl, const cchar_t *tr, const cchar_t *bl, const cchar_t *br) { #ifndef HAVE_WCHAR return ERR; #else int endy, endx, i, j, k, cw, pcw, tlcw, blcw, trcw, brcw; cchar_t left, right, bottom, top, topleft, topright, botleft, botright; nschar_t *np, *tnp; if ( ls && wcwidth( ls->vals[ 0 ])) memcpy( &left, ls, sizeof( cchar_t )); else memcpy( &left, WACS_VLINE, sizeof( cchar_t )); if ( rs && wcwidth( rs->vals[ 0 ])) memcpy( &right, rs, sizeof( cchar_t )); else memcpy( &right, WACS_VLINE, sizeof( cchar_t )); if ( ts && wcwidth( ts->vals[ 0 ])) memcpy( &top, ts, sizeof( cchar_t )); else memcpy( &top, WACS_HLINE, sizeof( cchar_t )); if ( bs && wcwidth( bs->vals[ 0 ])) memcpy( &bottom, bs, sizeof( cchar_t )); else memcpy( &bottom, WACS_HLINE, sizeof( cchar_t )); if ( tl && wcwidth( tl->vals[ 0 ])) memcpy( &topleft, tl, sizeof( cchar_t )); else memcpy( &topleft, WACS_ULCORNER, sizeof( cchar_t )); if ( tr && wcwidth( tr->vals[ 0 ])) memcpy( &topright, tr, sizeof( cchar_t )); else memcpy( &topright, WACS_URCORNER, sizeof( cchar_t )); if ( bl && wcwidth( bl->vals[ 0 ])) memcpy( &botleft, bl, sizeof( cchar_t )); else memcpy( &botleft, WACS_LLCORNER, sizeof( cchar_t )); if ( br && wcwidth( br->vals[ 0 ])) memcpy( &botright, br, sizeof( cchar_t )); else memcpy( &botright, WACS_LRCORNER, sizeof( cchar_t )); #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "wborder_set: left = %c, 0x%x\n", left.vals[0], left.attributes ); __CTRACE(__CTRACE_INPUT, "wborder_set: right = %c, 0x%x\n", right.vals[0], right.attributes ); __CTRACE(__CTRACE_INPUT, "wborder_set: top = %c, 0x%x\n", top.vals[0], top.attributes ); __CTRACE(__CTRACE_INPUT, "wborder_set: bottom = %c, 0x%x\n", bottom.vals[0], bottom.attributes ); __CTRACE(__CTRACE_INPUT, "wborder_set: topleft = %c, 0x%x\n", topleft.vals[0], topleft.attributes ); __CTRACE(__CTRACE_INPUT, "wborder_set: topright = %c, 0x%x\n", topright.vals[0], topright.attributes ); __CTRACE(__CTRACE_INPUT, "wborder_set: botleft = %c, 0x%x\n", botleft.vals[0], botleft.attributes ); __CTRACE(__CTRACE_INPUT, "wborder_set: botright = %c, 0x%x\n", botright.vals[0], botright.attributes ); #endif /* Merge window attributes */ left.attributes |= (left.attributes & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; left.attributes |= (left.attributes & __COLOR) ? (win->battr & ~__COLOR) : win->battr; right.attributes |= (right.attributes & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; right.attributes |= (right.attributes & __COLOR) ? (win->battr & ~__COLOR) : win->battr; top.attributes |= (top.attributes & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; top.attributes |= (top.attributes & __COLOR) ? (win->battr & ~__COLOR) : win->battr; bottom.attributes |= (bottom.attributes & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; bottom.attributes |= (bottom.attributes & __COLOR) ? (win->battr & ~__COLOR) : win->battr; topleft.attributes |= (topleft.attributes & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; topleft.attributes |= (topleft.attributes & __COLOR) ? (win->battr & ~__COLOR) : win->battr; topright.attributes |= (topright.attributes & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; topright.attributes |= (topright.attributes & __COLOR) ? (win->battr & ~__COLOR) : win->battr; botleft.attributes |= (botleft.attributes & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; botleft.attributes |= (botleft.attributes & __COLOR) ? (win->battr & ~__COLOR) : win->battr; botright.attributes |= (botright.attributes & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; botright.attributes |= (botright.attributes & __COLOR) ? (win->battr & ~__COLOR) : win->battr; endx = win->maxx - 1; endy = win->maxy - 1; /* Sides */ for (i = 1; i < endy; i++) { /* left border */ cw = wcwidth( left.vals[ 0 ]); if (cw < 0) cw = 1; for ( j = 0; j < cw; j++ ) { win->alines[i]->line[j].ch = left.vals[ 0 ]; win->alines[i]->line[j].attr = left.attributes; np = win->alines[i]->line[j].nsp; if (np) { while ( np ) { tnp = np->next; free( np ); np = tnp; } win->alines[i]->line[j].nsp = NULL; } if ( j ) SET_WCOL( win->alines[i]->line[j], -j ); else { SET_WCOL( win->alines[i]->line[j], cw ); if ( left.elements > 1 ) { for (k = 1; k < left.elements; k++) { np = malloc(sizeof(nschar_t)); if (!np) return ERR; np->ch = left.vals[ k ]; np->next = win->alines[i]->line[j].nsp; win->alines[i]->line[j].nsp = np; } } } } for ( j = cw; WCOL( win->alines[i]->line[j]) < 0; j++ ) { #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "wborder_set: clean out partial char[%d]", j); #endif /* DEBUG */ win->alines[i]->line[j].ch = ( wchar_t )btowc(win->bch); if (_cursesi_copy_nsp(win->bnsp, &win->alines[i]->line[j]) == ERR) return ERR; SET_WCOL( win->alines[i]->line[j], 1 ); } /* right border */ cw = wcwidth( right.vals[ 0 ]); if (cw < 0) cw = 1; pcw = WCOL( win->alines[i]->line[endx - cw]); for ( j = endx - cw + 1; j <= endx; j++ ) { win->alines[i]->line[j].ch = right.vals[ 0 ]; win->alines[i]->line[j].attr = right.attributes; np = win->alines[i]->line[j].nsp; if (np) { while ( np ) { tnp = np->next; free( np ); np = tnp; } win->alines[i]->line[j].nsp = NULL; } if ( j == endx - cw + 1 ) { SET_WCOL( win->alines[i]->line[j], cw ); if ( right.elements > 1 ) { for (k = 1; k < right.elements; k++) { np = malloc(sizeof(nschar_t)); if (!np) return ERR; np->ch = right.vals[ k ]; np->next = win->alines[i]->line[j].nsp; win->alines[i]->line[j].nsp = np; } } } else SET_WCOL( win->alines[i]->line[j], endx - cw + 1 - j ); } if ( pcw != 1 ) { #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "wborder_set: clean out partial chars[%d:%d]", endx - cw + pcw, endx - cw ); #endif /* DEBUG */ k = pcw < 0 ? endx -cw + pcw : endx - cw; for ( j = endx - cw; j >= k; j-- ) { win->alines[i]->line[j].ch = (wchar_t)btowc(win->bch); if (_cursesi_copy_nsp(win->bnsp, &win->alines[i]->line[j]) == ERR) return ERR; win->alines[i]->line[j].attr = win->battr; SET_WCOL( win->alines[i]->line[j], 1 ); } } } tlcw = wcwidth( topleft.vals[ 0 ]); if (tlcw < 0) tlcw = 1; blcw = wcwidth( botleft.vals[ 0 ]); if (blcw < 0) blcw = 1; trcw = wcwidth( topright.vals[ 0 ]); if (trcw < 0) trcw = 1; brcw = wcwidth( botright.vals[ 0 ]); if (brcw < 0) brcw = 1; /* upper border */ cw = wcwidth( top.vals[ 0 ]); if (cw < 0) cw = 1; for (i = tlcw; i <= min( endx - cw, endx - trcw ); i += cw ) { for ( j = 0; j < cw; j++ ) { win->alines[ 0 ]->line[i + j].ch = top.vals[ 0 ]; win->alines[ 0 ]->line[i + j].attr = top.attributes; np = win->alines[ 0 ]->line[i + j].nsp; if (np) { while ( np ) { tnp = np->next; free( np ); np = tnp; } win->alines[ 0 ]->line[i + j].nsp = NULL; } if ( j ) SET_WCOL( win->alines[ 0 ]->line[ i + j ], -j ); else { SET_WCOL( win->alines[ 0 ]->line[ i + j ], cw ); if ( top.elements > 1 ) { for ( k = 1; k < top.elements; k++ ) { np = malloc(sizeof(nschar_t)); if (!np) return ERR; np->ch = top.vals[ k ]; np->next = win->alines[0]->line[i + j].nsp; win->alines[0]->line[i + j].nsp = np; } } } } } while ( i <= endx - trcw ) { win->alines[0]->line[i].ch = ( wchar_t )btowc(( int ) win->bch ); if (_cursesi_copy_nsp(win->bnsp, &win->alines[0]->line[i]) == ERR) return ERR; win->alines[ 0 ]->line[ i ].attr = win->battr; SET_WCOL( win->alines[ 0 ]->line[ i ], 1 ); i++; } /* lower border */ for (i = blcw; i <= min( endx - cw, endx - brcw ); i += cw ) { for ( j = 0; j < cw; j++ ) { win->alines[ endy ]->line[i + j].ch = bottom.vals[ 0 ]; win->alines[endy]->line[i + j].attr = bottom.attributes; np = win->alines[ endy ]->line[i + j].nsp; if (np) { while ( np ) { tnp = np->next; free( np ); np = tnp; } win->alines[ endy ]->line[i + j].nsp = NULL; } if ( j ) SET_WCOL( win->alines[endy]->line[i + j], -j); else { SET_WCOL( win->alines[endy]->line[i + j], cw ); if ( bottom.elements > 1 ) { for ( k = 1; k < bottom.elements; k++ ) { np = malloc(sizeof(nschar_t)); if (!np) return ERR; np->ch = bottom.vals[ k ]; np->next = win->alines[endy]->line[i + j].nsp; win->alines[endy]->line[i + j].nsp = np; } } } } } while ( i <= endx - brcw ) { win->alines[endy]->line[i].ch = (wchar_t)btowc((int) win->bch ); if (_cursesi_copy_nsp(win->bnsp, &win->alines[endy]->line[i]) == ERR) return ERR; win->alines[ endy ]->line[ i ].attr = win->battr; SET_WCOL( win->alines[ endy ]->line[ i ], 1 ); i++; } /* Corners */ if (!(win->maxx == LINES && win->maxy == COLS && (win->flags & __SCROLLOK) && (win->flags & __SCROLLWIN))) { for ( i = 0; i < tlcw; i++ ) { win->alines[ 0 ]->line[i].ch = topleft.vals[ 0 ]; win->alines[ 0 ]->line[i].attr = topleft.attributes; np = win->alines[ 0 ]->line[i].nsp; if (np) { while ( np ) { tnp = np->next; free( np ); np = tnp; } win->alines[ 0 ]->line[i].nsp = NULL; } if ( i ) SET_WCOL( win->alines[ 0 ]->line[ i ], -i ); else { SET_WCOL( win->alines[ 0 ]->line[ i ], tlcw ); if ( topleft.elements > 1 ) { for ( k = 1; k < topleft.elements; k++ ) { np = malloc(sizeof(nschar_t)); if (!np) return ERR; np->ch = topleft.vals[ k ]; np->next = win->alines[ 0 ]->line[i].nsp; win->alines[ 0 ]->line[i].nsp = np; } } } } for ( i = endx - trcw + 1; i <= endx; i++ ) { win->alines[ 0 ]->line[i].ch = topright.vals[ 0 ]; win->alines[ 0 ]->line[i].attr = topright.attributes; np = win->alines[ 0 ]->line[i].nsp; if (np) { while ( np ) { tnp = np->next; free( np ); np = tnp; } win->alines[ 0 ]->line[i].nsp = NULL; } if ( i == endx - trcw + 1 ) { SET_WCOL( win->alines[ 0 ]->line[ i ], trcw ); if ( topright.elements > 1 ) { for ( k = 1; k < topright.elements; k++ ) { np = malloc(sizeof(nschar_t)); if (!np) return ERR; np->ch = topright.vals[ k ]; np->next = win->alines[0]->line[i].nsp; win->alines[ 0 ]->line[i].nsp = np; } } } else SET_WCOL( win->alines[ 0 ]->line[ i ], endx - trcw + 1 - i ); } for ( i = 0; i < blcw; i++ ) { win->alines[ endy ]->line[i].ch = botleft.vals[ 0 ]; win->alines[ endy ]->line[i].attr = botleft.attributes; np = win->alines[ endy ]->line[i].nsp; if (np) { while ( np ) { tnp = np->next; free( np ); np = tnp; } win->alines[ endy ]->line[i].nsp = NULL; } if ( i ) SET_WCOL( win->alines[endy]->line[i], -i ); else { SET_WCOL( win->alines[endy]->line[i], blcw ); if ( botleft.elements > 1 ) { for ( k = 1; k < botleft.elements; k++ ) { np = malloc(sizeof(nschar_t)); if (!np) return ERR; np->ch = botleft.vals[ k ]; np->next = win->alines[endy]->line[i].nsp; win->alines[endy]->line[i].nsp = np; } } } } for ( i = endx - brcw + 1; i <= endx; i++ ) { win->alines[ endy ]->line[i].ch = botright.vals[ 0 ]; win->alines[ endy ]->line[i].attr = botright.attributes; np = win->alines[ endy ]->line[i].nsp; if (np) { while ( np ) { tnp = np->next; free( np ); np = tnp; } win->alines[ endy ]->line[i].nsp = NULL; } if ( i == endx - brcw + 1 ) { SET_WCOL( win->alines[ endy ]->line[ i ], brcw ); if ( botright.elements > 1 ) { for ( k = 1; k < botright.elements; k++ ) { np = malloc(sizeof(nschar_t)); if (!np) return ERR; np->ch = botright.vals[ k ]; np->next = win->alines[endy]->line[i].nsp; win->alines[endy]->line[i].nsp = np; } } } else SET_WCOL( win->alines[ endy ]->line[ i ], endx - brcw + 1 - i ); } } __touchwin(win); return (OK); #endif /* HAVE_WCHAR */ }
/* * __resizewin -- * Resize the given window. */ static int __resizewin(WINDOW *win, int nlines, int ncols) { __LINE *lp, *olp, **newlines, *newlspace; __LDATA *sp; __LDATA *newwspace; int i, j; int y, x; WINDOW *swin; #ifdef DEBUG __CTRACE(__CTRACE_WINDOW, "resize: (%p, %d, %d)\n", win, nlines, ncols); __CTRACE(__CTRACE_WINDOW, "resize: win->wattr = %08x\n", win->wattr); __CTRACE(__CTRACE_WINDOW, "resize: win->flags = %#.4x\n", win->flags); __CTRACE(__CTRACE_WINDOW, "resize: win->maxy = %d\n", win->maxy); __CTRACE(__CTRACE_WINDOW, "resize: win->maxx = %d\n", win->maxx); __CTRACE(__CTRACE_WINDOW, "resize: win->begy = %d\n", win->begy); __CTRACE(__CTRACE_WINDOW, "resize: win->begx = %d\n", win->begx); __CTRACE(__CTRACE_WINDOW, "resize: win->scr_t = %d\n", win->scr_t); __CTRACE(__CTRACE_WINDOW, "resize: win->scr_b = %d\n", win->scr_b); #endif /* * free up any non-spacing storage before we lose the * pointers... */ #ifdef HAVE_WCHAR __cursesi_win_free_nsp(win); #endif if (nlines <= 0 || ncols <= 0) nlines = ncols = 0; else { /* Reallocate line pointer array and line space. */ newlines = realloc(win->alines, nlines * sizeof(__LINE *)); if (newlines == NULL) return ERR; win->alines = newlines; newlspace = realloc(win->lspace, nlines * sizeof(__LINE)); if (newlspace == NULL) return ERR; win->lspace = newlspace; } /* Don't allocate window and line space if it's a subwindow */ if (win->orig == NULL) { /* * Allocate window space in one chunk. */ if (ncols != 0) { newwspace = realloc(win->wspace, ncols * nlines * sizeof(__LDATA)); if (newwspace == NULL) return ERR; win->wspace = newwspace; } /* * Point line pointers to line space, and lines themselves into * window space. */ for (lp = win->lspace, i = 0; i < nlines; i++, lp++) { win->alines[i] = lp; lp->line = &win->wspace[i * ncols]; #ifdef DEBUG lp->sentinel = SENTINEL_VALUE; #endif lp->firstchp = &lp->firstch; lp->lastchp = &lp->lastch; lp->firstch = 0; lp->lastch = ncols - 1; lp->flags = __ISDIRTY; } } else { win->ch_off = win->begx - win->orig->begx; /* Point line pointers to line space. */ for (lp = win->lspace, i = 0; i < nlines; i++, lp++) { win->alines[i] = lp; olp = win->orig->alines[i + win->begy - win->orig->begy]; lp->line = &olp->line[win->ch_off]; #ifdef DEBUG lp->sentinel = SENTINEL_VALUE; #endif lp->firstchp = &olp->firstch; lp->lastchp = &olp->lastch; lp->flags = __ISDIRTY; } } win->cury = win->curx = 0; win->maxy = nlines; win->maxx = ncols; win->scr_b = win->maxy - 1; __swflags(win); /* * we must zot the window contents otherwise lines may pick * up attributes from the previous line when the window is * made smaller. The client will redraw the window anyway * so this is no big deal. */ for (i = 0; i < win->maxy; i++) { lp = win->alines[i]; for (sp = lp->line, j = 0; j < win->maxx; j++, sp++) { sp->attr = 0; #ifndef HAVE_WCHAR sp->ch = win->bch; #else sp->ch = ( wchar_t )btowc(( int ) win->bch ); sp->nsp = NULL; if (_cursesi_copy_nsp(win->bnsp, sp) == ERR) return ERR; SET_WCOL( *sp, 1 ); #endif /* HAVE_WCHAR */ } lp->hash = __hash((char *)(void *)lp->line, (size_t) (ncols * __LDATASIZE)); } #ifdef DEBUG __CTRACE(__CTRACE_WINDOW, "resize: win->wattr = %08x\n", win->wattr); __CTRACE(__CTRACE_WINDOW, "resize: win->flags = %#.4x\n", win->flags); __CTRACE(__CTRACE_WINDOW, "resize: win->maxy = %d\n", win->maxy); __CTRACE(__CTRACE_WINDOW, "resize: win->maxx = %d\n", win->maxx); __CTRACE(__CTRACE_WINDOW, "resize: win->begy = %d\n", win->begy); __CTRACE(__CTRACE_WINDOW, "resize: win->begx = %d\n", win->begx); __CTRACE(__CTRACE_WINDOW, "resize: win->scr_t = %d\n", win->scr_t); __CTRACE(__CTRACE_WINDOW, "resize: win->scr_b = %d\n", win->scr_b); #endif if (win->orig == NULL) { /* bound subwindows to new size and fixup their pointers */ for (swin = win->nextp; swin != win; swin = swin->nextp) { y = swin->reqy; if (swin->begy > win->begy + win->maxy) swin->begy = win->begy + win->maxy - 1; if (swin->begy + y > win->begy + win->maxy) y = 0; if (y <= 0) y += win->begy + win->maxy - swin->begy; if (y < 1) y = 1; x = swin->reqx; if (swin->begx > win->begx + win->maxx) swin->begx = win->begx + win->maxx - 1; if (swin->begx + x > win->begx + win->maxx) x = 0; if (x <= 0) x += win->begy + win->maxx - swin->begx; if (x < 1) x = 1; __resizewin(swin, y, x); } } return OK; }