/* * winsertln -- * Do an insert-line on the window, leaving (cury, curx) unchanged. */ int winsertln(WINDOW *win) { register int y, i; register __LINE *temp; #ifdef DEBUG __CTRACE("insertln: (%0.2o)\n", win); #endif if (win->orig == NULL) temp = win->lines[win->maxy - 1]; for (y = win->maxy - 1; y > (int) win->cury; --y) { win->lines[y]->flags &= ~__ISPASTEOL; win->lines[y - 1]->flags &= ~__ISPASTEOL; if (win->orig == NULL) win->lines[y] = win->lines[y - 1]; else (void)memcpy(win->lines[y]->line, win->lines[y - 1]->line, win->maxx * __LDATASIZE); __touchline(win, y, 0, win->maxx - 1, 0); } if (win->orig == NULL) win->lines[y] = temp; else temp = win->lines[y]; for(i = 0; i < win->maxx; i++) { temp->line[i].ch = ' '; temp->line[i].attr = 0; } __touchline(win, y, 0, win->maxx - 1, 0); if (win->orig == NULL) __id_subwins(win); return (OK); }
/* * wtouchln -- * If changed is 1 then touch n lines starting at line. If changed * is 0 then mark the lines as unchanged. */ int wtouchln(WINDOW *win, int line, int n, int changed) { int y; __LINE *wlp; #ifdef DEBUG __CTRACE(__CTRACE_LINE, "wtouchln: (%p) %d, %d, %d\n", win, line, n, changed); #endif if (line + n > win->maxy) line = win->maxy - n; for (y = line; y < line + n; y++) { if (changed == 1) __touchline(win, y, 0, (int) win->maxx - 1); else { wlp = win->alines[y]; if (*wlp->firstchp >= win->ch_off && *wlp->firstchp < win->maxx + win->ch_off) *wlp->firstchp = win->maxx + win->ch_off; if (*wlp->lastchp >= win->ch_off && *wlp->lastchp < win->maxx + win->ch_off) *wlp->lastchp = win->ch_off; wlp->flags &= ~__ISDIRTY; } } return OK; }
/* * touchoverlap -- * Touch, on win2, the part that overlaps with win1. */ int touchoverlap(WINDOW *win1, WINDOW *win2) { int y, endy, endx, starty, startx; #ifdef DEBUG __CTRACE(__CTRACE_WINDOW, "touchoverlap: (%p, %p);\n", win1, win2); #endif starty = max(win1->begy, win2->begy); startx = max(win1->begx, win2->begx); endy = min(win1->maxy + win1->begy, win2->maxy + win2->begy); endx = min(win1->maxx + win1->begx, win2->maxx + win2->begx); #ifdef DEBUG __CTRACE(__CTRACE_WINDOW, "touchoverlap: from (%d,%d) to (%d,%d)\n", starty, startx, endy, endx); __CTRACE(__CTRACE_WINDOW, "touchoverlap: win1 (%d,%d) to (%d,%d)\n", win1->begy, win1->begx, win1->begy + win1->maxy, win1->begx + win1->maxx); __CTRACE(__CTRACE_WINDOW, "touchoverlap: win2 (%d,%d) to (%d,%d)\n", win2->begy, win2->begx, win2->begy + win2->maxy, win2->begx + win2->maxx); #endif if (starty >= endy || startx >= endx) return (OK); starty -= win2->begy; startx -= win2->begx; endy -= win2->begy; endx -= win2->begx; for (--endx, y = starty; y < endy; y++) __touchline(win2, y, startx, endx); return (OK); }
/* * winsch -- * Do an insert-char on the line, leaving (cury, curx) unchanged. */ int winsch(register WINDOW *win, char ch) { register __LDATA *end, *temp1, *temp2; end = &win->lines[win->cury]->line[win->curx]; temp1 = &win->lines[win->cury]->line[win->maxx - 1]; temp2 = temp1 - 1; while (temp1 > end) { (void)memcpy(temp1, temp2, sizeof(__LDATA)); temp1--, temp2--; } temp1->ch = ch; temp1->attr &= ~__STANDOUT; __touchline(win, win->cury, win->curx, win->maxx - 1, 0); if (win->cury == LINES - 1 && (win->lines[LINES - 1]->line[COLS - 1].ch != ' ' || win->lines[LINES -1]->line[COLS - 1].attr != 0)) if (win->flags & __SCROLLOK) { wrefresh(win); scroll(win); win->cury--; } else return (ERR); return (OK); }
int __touchwin(WINDOW *win) { int y, maxy; #ifdef DEBUG __CTRACE(__CTRACE_LINE, "__touchwin: (%p)\n", win); #endif maxy = win->maxy; for (y = 0; y < maxy; y++) __touchline(win, y, 0, (int) win->maxx - 1); return (OK); }
int __touchwin(WINDOW *win) { register int y, maxy; #ifdef DEBUG __CTRACE("touchwin: (%0.2o)\n", win); #endif maxy = win->maxy; for (y = 0; y < maxy; y++) __touchline(win, y, 0, win->maxx - 1, 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 }
/* * touchline -- * Touch a given line. */ int touchline(WINDOW *win, int y, int sx, int ex) { return (__touchline(win, y, sx, ex, 1)); }
/* * getwin -- * Read window data from file */ WINDOW * getwin(FILE *fp) { int major, minor; WINDOW *wtmp, *win; int y, x; __LDATA *sp; #ifdef DEBUG __CTRACE(__CTRACE_FILEIO, "getwin\n"); #endif /* Check library version */ if (fread(&major, sizeof(int), 1, fp) != 1) return NULL; if (fread(&minor, sizeof(int), 1, fp) != 1) return NULL; if(major != CURSES_LIB_MAJOR || minor != CURSES_LIB_MINOR) return NULL; /* Window parameters */ wtmp = (WINDOW *)malloc(sizeof(WINDOW)); if (wtmp == NULL) return NULL; if (fread(wtmp, sizeof(WINDOW), 1, fp) != 1) goto error0; win = __newwin(_cursesi_screen, wtmp->maxy, wtmp->maxx, wtmp->begy, wtmp->begx, FALSE); if (win == NULL) goto error0; win->cury = wtmp->cury; win->curx = wtmp->curx; win->reqy = wtmp->reqy; win->reqx = wtmp->reqx; win->flags = wtmp->flags; win->delay = wtmp->delay; win->wattr = wtmp->wattr; win->bch = wtmp->bch; win->battr = wtmp->battr; win->scr_t = wtmp->scr_t; win->scr_b = wtmp->scr_b; free(wtmp); wtmp = NULL; __swflags(win); #ifdef HAVE_WCHAR if (__getnsp(win->bnsp, fp) == ERR) goto error1; #endif /* HAVE_WCHAR */ /* Lines and line data */ for (y = 0; y < win->maxy; y++) { for (sp = win->alines[y]->line, x = 0; x < win->maxx; x++, sp++) { if (fread(&sp->ch, sizeof(wchar_t), 1, fp) != 1) goto error1; if (fread(&sp->attr, sizeof(attr_t), 1, fp) != 1) goto error1; #ifdef HAVE_WCHAR if (sp->nsp != NULL) { if (__getnsp(win->bnsp, fp) == ERR) goto error1; } #endif /* HAVE_WCHAR */ } __touchline(win, y, 0, (int) win->maxx - 1); } #ifdef DEBUG __CTRACE(__CTRACE_FILEIO, "getwin: win = 0x%p\n", win); #endif return win; error1: delwin(win); error0: if (wtmp) free(wtmp); return NULL; }