getcchar(const cchar_t * wcval, wchar_t * wch, attr_t * attrs, short *color_pair, void *opts) { wchar_t *wp; int len; int code = ERR; TR(TRACE_CCALLS, (T_CALLED("getcchar(%p,%p,%p,%p,%p)"), wcval, wch, attrs, color_pair, opts)); if (opts == NULL) { len = (wp = wmemchr(wcval->chars, L'\0', CCHARW_MAX)) ? wp - wcval->chars : CCHARW_MAX; if (wch == NULL) { code = len; } else if (len >= 0) { *attrs = AttrOf(*wcval); *color_pair = AttrOf(*wcval) & A_COLOR; wmemcpy(wch, wcval->chars, (unsigned) len); wch[len] = L'\0'; code = OK; } } TR(TRACE_CCALLS, (T_RETURN("%d"), code)); return (code); }
static NCURSES_INLINE void #endif wbkgrndset(WINDOW *win, const ARG_CH_T ch) { T((T_CALLED("wbkgdset(%p,%s)"), (void *) win, _tracech_t(ch))); if (win) { attr_t off = AttrOf(win->_nc_bkgd); attr_t on = AttrOf(CHDEREF(ch)); toggle_attr_off(WINDOW_ATTRS(win), off); toggle_attr_on(WINDOW_ATTRS(win), on); #if NCURSES_EXT_COLORS { int pair; if ((pair = GetPair(win->_nc_bkgd)) != 0) SET_WINDOW_PAIR(win, 0); if ((pair = GetPair(CHDEREF(ch))) != 0) SET_WINDOW_PAIR(win, pair); } #endif if (CharOf(CHDEREF(ch)) == L('\0')) { SetChar(win->_nc_bkgd, BLANK_TEXT, AttrOf(CHDEREF(ch))); if_EXT_COLORS(SetPair(win->_nc_bkgd, GetPair(CHDEREF(ch)))); } else { win->_nc_bkgd = CHDEREF(ch); } #if USE_WIDEC_SUPPORT /* * If we're compiled for wide-character support, _bkgrnd is the * preferred location for the background information since it stores * more than _bkgd. Update _bkgd each time we modify _bkgrnd, so the * macro getbkgd() will work. */ { cchar_t wch; int tmp; (void) wgetbkgrnd(win, &wch); tmp = _nc_to_char((wint_t) CharOf(wch)); win->_bkgd = (((tmp == EOF) ? ' ' : (chtype) tmp) | (AttrOf(wch) & ALL_BUT_COLOR) | ColorPair(GET_WINDOW_PAIR(win))); } #endif } returnVoid; }
static NCURSES_INLINE int #undef wbkgrnd #endif wbkgrnd(WINDOW *win, const ARG_CH_T ch) { int code = ERR; int x, y; NCURSES_CH_T new_bkgd = CHDEREF(ch); T((T_CALLED("wbkgd(%p,%s)"), (void *) win, _tracech_t(ch))); if (win) { NCURSES_CH_T old_bkgrnd; wgetbkgrnd(win, &old_bkgrnd); (void) wbkgrndset(win, CHREF(new_bkgd)); (void) wattrset(win, AttrOf(win->_nc_bkgd)); for (y = 0; y <= win->_maxy; y++) { for (x = 0; x <= win->_maxx; x++) { if (CharEq(win->_line[y].text[x], old_bkgrnd)) { win->_line[y].text[x] = win->_nc_bkgd; } else { NCURSES_CH_T wch = win->_line[y].text[x]; RemAttr(wch, (~(A_ALTCHARSET | A_CHARTEXT))); win->_line[y].text[x] = _nc_render(win, wch); } } } touchwin(win); _nc_synchook(win); code = OK; } returnCode(code); }
static NCURSES_INLINE chtype _my_render(WINDOW *win, chtype ch) { NCURSES_CH_T wch; SetChar2(wch, ch); wch = _nc_render(win, wch); return CharOf(wch) | AttrOf(wch); }
static NCURSES_INLINE NCURSES_CH_T render_char(WINDOW *win, NCURSES_CH_T ch) /* compute a rendition of the given char correct for the current context */ { attr_t a = WINDOW_ATTRS(win); int pair = GetPair(ch); if (ISBLANK(ch) && AttrOf(ch) == A_NORMAL && pair == 0) { /* color/pair in attrs has precedence over bkgrnd */ ch = win->_nc_bkgd; SetAttr(ch, a | AttrOf(win->_nc_bkgd)); if ((pair = GET_WINDOW_PAIR(win)) == 0) pair = GetPair(win->_nc_bkgd); SetPair(ch, pair); } else { /* color in attrs has precedence over bkgrnd */ a |= AttrOf(win->_nc_bkgd) & COLOR_MASK(a); /* color in ch has precedence */ if (pair == 0) { if ((pair = GET_WINDOW_PAIR(win)) == 0) pair = GetPair(win->_nc_bkgd); } #if 0 if (pair > 255) { NCURSES_CH_T fixme = ch; SetPair(fixme, pair); } #endif AddAttr(ch, (a & COLOR_MASK(AttrOf(ch)))); SetPair(ch, pair); } TR(TRACE_VIRTPUT, ("render_char bkg %s (%d), attrs %s (%d) -> ch %s (%d)", _tracech_t2(1, CHREF(win->_nc_bkgd)), GetPair(win->_nc_bkgd), _traceattr(WINDOW_ATTRS(win)), GET_WINDOW_PAIR(win), _tracech_t2(3, CHREF(ch)), GetPair(ch))); return (ch); }
winch(WINDOW *win) { T((T_CALLED("winch(%p)"), win)); if (win != 0) { returnChar(CharOf(win->_line[win->_cury].text[win->_curx]) | AttrOf(win->_line[win->_cury].text[win->_curx])); } else { returnChar(0); } }
slk_attr(void) { T((T_CALLED("slk_attr()"))); if (SP != 0 && SP->_slk != 0) { attr_t result = AttrOf(SP->_slk->attr) & ALL_BUT_COLOR; int pair = GetPair(SP->_slk->attr); result |= COLOR_PAIR(pair); returnAttr(result); } else returnAttr(0); }
_nc_build_wch(WINDOW *win, ARG_CH_T ch) { char *buffer = WINDOW_EXT(win, addch_work); int len; int x = win->_curx; int y = win->_cury; mbstate_t state; wchar_t result; if ((WINDOW_EXT(win, addch_used) != 0) && (WINDOW_EXT(win, addch_x) != x || WINDOW_EXT(win, addch_y) != y)) { /* discard the incomplete multibyte character */ WINDOW_EXT(win, addch_used) = 0; TR(TRACE_VIRTPUT, ("Alert discarded multibyte on move (%d,%d) -> (%d,%d)", WINDOW_EXT(win, addch_y), WINDOW_EXT(win, addch_x), y, x)); } WINDOW_EXT(win, addch_x) = x; WINDOW_EXT(win, addch_y) = y; init_mb(state); buffer[WINDOW_EXT(win, addch_used)] = (char) CharOf(CHDEREF(ch)); WINDOW_EXT(win, addch_used) += 1; buffer[WINDOW_EXT(win, addch_used)] = '\0'; if ((len = (int) mbrtowc(&result, buffer, (size_t) WINDOW_EXT(win, addch_used), &state)) > 0) { attr_t attrs = AttrOf(CHDEREF(ch)); if_EXT_COLORS(int pair = GetPair(CHDEREF(ch))); SetChar(CHDEREF(ch), result, attrs); if_EXT_COLORS(SetPair(CHDEREF(ch), pair)); WINDOW_EXT(win, addch_used) = 0; } else if (len == -1) { /* * An error occurred. We could either discard everything, * or assume that the error was in the previous input. * Try the latter. */ TR(TRACE_VIRTPUT, ("Alert! mbrtowc returns error")); /* handle this with unctrl() */ WINDOW_EXT(win, addch_used) = 0; } return len; }
/* * Write the soft labels to the soft-key window. */ static void slk_intern_refresh(SLK * slk) { int i; int fmt = SP->slk_format; for (i = 0; i < slk->labcnt; i++) { if (slk->dirty || slk->ent[i].dirty) { if (slk->ent[i].visible) { if (num_labels > 0 && SLK_STDFMT(fmt)) { if (i < num_labels) { TPUTS_TRACE("plab_norm"); putp(TPARM_2(plab_norm, i + 1, slk->ent[i].form_text)); } } else { if (fmt == 4) slk_paint_info(slk->win); wmove(slk->win, SLK_LINES(fmt) - 1, slk->ent[i].ent_x); if (SP->_slk) { wattrset(slk->win, AttrOf(SP->_slk->attr)); } waddstr(slk->win, slk->ent[i].form_text); /* if we simulate SLK's, it's looking much more natural to use the current ATTRIBUTE also for the label window */ wattrset(slk->win, WINDOW_ATTRS(stdscr)); } } slk->ent[i].dirty = FALSE; } } slk->dirty = FALSE; if (num_labels > 0) { if (slk->hidden) { TPUTS_TRACE("label_off"); putp(label_off); } else { TPUTS_TRACE("label_on"); putp(label_on); } } }
winchnstr(WINDOW *win, chtype *str, int n) { int i = 0; T((T_CALLED("winchnstr(%p,%p,%d)"), (void *) win, (void *) str, n)); if (!str) returnCode(0); if (win) { for (; (n < 0 || (i < n)) && (win->_curx + i <= win->_maxx); i++) str[i] = (chtype) CharOf(win->_line[win->_cury].text[win->_curx + i]) | AttrOf(win->_line[win->_cury].text[win->_curx + i]); } str[i] = (chtype) 0; returnCode(i); }
getcchar(const cchar_t *wcval, wchar_t *wch, attr_t *attrs, short *color_pair, void *opts) { wchar_t *wp; int len; int code = ERR; TR(TRACE_CCALLS, (T_CALLED("getcchar(%p,%p,%p,%p,%p)"), (const void *) wcval, (void *) wch, (void *) attrs, (void *) color_pair, opts)); if (opts == NULL) { len = ((wp = wmemchr(wcval->chars, L'\0', CCHARW_MAX)) ? (int) (wp - wcval->chars) : CCHARW_MAX); if (wch == NULL) { /* * If the value is a null, set the length to 1. * If the value is not a null, return the length plus 1 for null. */ code = (len < CCHARW_MAX) ? (len + 1) : CCHARW_MAX; } else if (attrs == 0 || color_pair == 0) { code = ERR; } else if (len >= 0) { *attrs = AttrOf(*wcval) & A_ATTRIBUTES; *color_pair = (short) GetPair(*wcval); wmemcpy(wch, wcval->chars, (unsigned) len); wch[len] = L'\0'; code = OK; } } TR(TRACE_CCALLS, (T_RETURN("%d"), code)); return (code); }
_tracedump(const char *name, WINDOW *win) { static char *buf = 0; static size_t used = 0; int i, j, n, width; /* compute narrowest possible display width */ for (width = i = 0; i <= win->_maxy; ++i) { n = 0; for (j = 0; j <= win->_maxx; ++j) if (CharOf(win->_line[i].text[j]) != L(' ') || AttrOf(win->_line[i].text[j]) != A_NORMAL) n = j; if (n > width) width = n; } if (width < win->_maxx) ++width; if (++width + 1 > (int) used) { used = 2 * (width + 1); buf = typeRealloc(char, used, buf); }
_tracedump(const char *name, WINDOW *win) { int i, j, n, width; /* compute narrowest possible display width */ for (width = i = 0; i <= win->_maxy; ++i) { n = 0; for (j = 0; j <= win->_maxx; ++j) { if (CharOf(win->_line[i].text[j]) != L(' ') || AttrOf(win->_line[i].text[j]) != A_NORMAL || GetPair(win->_line[i].text[j]) != 0) { n = j; } } if (n > width) width = n; } if (width < win->_maxx) ++width; if (++width + 1 > (int) my_length) { my_length = 2 * (width + 1); my_buffer = typeRealloc(char, my_length, my_buffer); }
char *_tracechtype2(int bufnum, chtype ch) { char *buf = _nc_trace_buf(bufnum, BUFSIZ); char *found = 0; strcpy(buf, "{"); if (ch & A_ALTCHARSET) { char *cp; static const struct {unsigned int val; const char *name;} names[] = { {'l', "ACS_ULCORNER"}, /* upper left corner */ {'m', "ACS_LLCORNER"}, /* lower left corner */ {'k', "ACS_URCORNER"}, /* upper right corner */ {'j', "ACS_LRCORNER"}, /* lower right corner */ {'t', "ACS_LTEE"}, /* tee pointing right */ {'u', "ACS_RTEE"}, /* tee pointing left */ {'v', "ACS_BTEE"}, /* tee pointing up */ {'w', "ACS_TTEE"}, /* tee pointing down */ {'q', "ACS_HLINE"}, /* horizontal line */ {'x', "ACS_VLINE"}, /* vertical line */ {'n', "ACS_PLUS"}, /* large plus or crossover */ {'o', "ACS_S1"}, /* scan line 1 */ {'s', "ACS_S9"}, /* scan line 9 */ {'`', "ACS_DIAMOND"}, /* diamond */ {'a', "ACS_CKBOARD"}, /* checker board (stipple) */ {'f', "ACS_DEGREE"}, /* degree symbol */ {'g', "ACS_PLMINUS"}, /* plus/minus */ {'~', "ACS_BULLET"}, /* bullet */ {',', "ACS_LARROW"}, /* arrow pointing left */ {'+', "ACS_RARROW"}, /* arrow pointing right */ {'.', "ACS_DARROW"}, /* arrow pointing down */ {'-', "ACS_UARROW"}, /* arrow pointing up */ {'h', "ACS_BOARD"}, /* board of squares */ {'i', "ACS_LANTERN"}, /* lantern symbol */ {'0', "ACS_BLOCK"}, /* solid square block */ {'p', "ACS_S3"}, /* scan line 3 */ {'r', "ACS_S7"}, /* scan line 7 */ {'y', "ACS_LEQUAL"}, /* less/equal */ {'z', "ACS_GEQUAL"}, /* greater/equal */ {'{', "ACS_PI"}, /* Pi */ {'|', "ACS_NEQUAL"}, /* not equal */ {'}', "ACS_STERLING"}, /* UK pound sign */ {'\0',(char *)0} }, *sp; for (cp = acs_chars; cp[0] && cp[1]; cp += 2) { if (TextOf(cp[1]) == TextOf(ch)) { found = cp; /* don't exit from loop - there may be redefinitions */ } } if (found != 0) { ch = TextOf(*found); for (sp = names; sp->val; sp++) if (sp->val == ch) { (void) strcat(buf, sp->name); ch &= ~A_ALTCHARSET; break; } } } if (found == 0) (void) strcat(buf, _tracechar(TextOf(ch))); if (AttrOf(ch) != A_NORMAL) (void) sprintf(buf + strlen(buf), " | %s", _traceattr2(bufnum+20,AttrOf(ch))); strcat(buf, "}"); return(buf); }
static NCURSES_INLINE int wadd_wch_nosync(WINDOW *win, cchar_t ch) /* the workhorse function -- add a character to the given window */ { NCURSES_SIZE_T x, y; wchar_t *s; int tabsize = 8; #if USE_REENTRANT SCREEN *sp = _nc_screen_of(win); #endif /* * If we are using the alternate character set, forget about locale. * Otherwise, if the locale claims the code is printable, treat it that * way. */ if ((AttrOf(ch) & A_ALTCHARSET) || iswprint((wint_t) CharOf(ch))) return wadd_wch_literal(win, ch); /* * Handle carriage control and other codes that are not printable, or are * known to expand to more than one character according to unctrl(). */ x = win->_curx; y = win->_cury; switch (CharOf(ch)) { case '\t': #if USE_REENTRANT tabsize = *ptrTabsize(sp); #else tabsize = TABSIZE; #endif x = (NCURSES_SIZE_T) (x + (tabsize - (x % tabsize))); /* * Space-fill the tab on the bottom line so that we'll get the * "correct" cursor position. */ if ((!win->_scroll && (y == win->_regbottom)) || (x <= win->_maxx)) { cchar_t blank = blankchar; AddAttr(blank, AttrOf(ch)); while (win->_curx < x) { if (wadd_wch_literal(win, blank) == ERR) return (ERR); } break; } else { wclrtoeol(win); win->_flags |= _WRAPPED; if (newline_forces_scroll(win, &y)) { x = win->_maxx; if (win->_scroll) { scroll(win); x = 0; } } else { x = 0; } } break; case '\n': wclrtoeol(win); if (newline_forces_scroll(win, &y)) { if (win->_scroll) scroll(win); else return (ERR); } /* FALLTHRU */ case '\r': x = 0; win->_flags &= ~_WRAPPED; break; case '\b': if (x == 0) return (OK); x--; win->_flags &= ~_WRAPPED; break; default: if ((s = wunctrl(&ch)) != 0) { while (*s) { cchar_t sch; SetChar(sch, *s++, AttrOf(ch)); if_EXT_COLORS(SetPair(sch, GetPair(ch))); if (wadd_wch_literal(win, sch) == ERR) return ERR; } return OK; } return ERR; } win->_curx = x; win->_cury = y; return OK; }
pnoutrefresh(WINDOW *win, int pminrow, int pmincol, int sminrow, int smincol, int smaxrow, int smaxcol) { NCURSES_SIZE_T i, j; NCURSES_SIZE_T m, n; NCURSES_SIZE_T pmaxrow; NCURSES_SIZE_T pmaxcol; SCREEN *sp; #if USE_SCROLL_HINTS const int my_len = 2; /* parameterize the threshold for hardscroll */ NCURSES_SIZE_T displaced; bool wide; #endif T((T_CALLED("pnoutrefresh(%p, %d, %d, %d, %d, %d, %d)"), (void *) win, pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol)); if (win == 0) returnCode(ERR); if (!(win->_flags & _ISPAD)) returnCode(ERR); sp = _nc_screen_of(win); /* negative values are interpreted as zero */ if (pminrow < 0) pminrow = 0; if (pmincol < 0) pmincol = 0; if (sminrow < 0) sminrow = 0; if (smincol < 0) smincol = 0; pmaxrow = pminrow + smaxrow - sminrow; pmaxcol = pmincol + smaxcol - smincol; T((" pminrow + smaxrow - sminrow %ld, win->_maxy %ld", (long) pmaxrow, (long) win->_maxy)); T((" pmincol + smaxcol - smincol %ld, win->_maxx %ld", (long) pmaxcol, (long) win->_maxx)); /* * Trim the caller's screen size back to the actual limits. */ if (pmaxrow > win->_maxy) { smaxrow -= (pmaxrow - win->_maxy); pmaxrow = pminrow + smaxrow - sminrow; } if (pmaxcol > win->_maxx) { smaxcol -= (pmaxcol - win->_maxx); pmaxcol = pmincol + smaxcol - smincol; } if (smaxrow >= screen_lines(sp) || smaxcol >= screen_columns(sp) || sminrow > smaxrow || smincol > smaxcol) returnCode(ERR); T(("pad being refreshed")); #if USE_SCROLL_HINTS if (win->_pad._pad_y >= 0) { displaced = pminrow - win->_pad._pad_y - (sminrow - win->_pad._pad_top); T(("pad being shifted by %d line(s)", displaced)); } else displaced = 0; #endif /* * For pure efficiency, we'd want to transfer scrolling information * from the pad to newscr whenever the window is wide enough that * its update will dominate the cost of the update for the horizontal * band of newscr that it occupies. Unfortunately, this threshold * tends to be complex to estimate, and in any case scrolling the * whole band and rewriting the parts outside win's image would look * really ugly. So. What we do is consider the pad "wide" if it * either (a) occupies the whole width of newscr, or (b) occupies * all but at most one column on either vertical edge of the screen * (this caters to fussy people who put boxes around full-screen * windows). Note that changing this formula will not break any code, * merely change the costs of various update cases. */ #if USE_SCROLL_HINTS wide = (smincol < my_len && smaxcol > (NewScreen(sp)->_maxx - my_len)); #endif for (i = pminrow, m = sminrow + win->_yoffset; i <= pmaxrow && m <= NewScreen(sp)->_maxy; i++, m++) { register struct ldat *nline = &NewScreen(sp)->_line[m]; register struct ldat *oline = &win->_line[i]; for (j = pmincol, n = smincol; j <= pmaxcol; j++, n++) { NCURSES_CH_T ch = oline->text[j]; #if USE_WIDEC_SUPPORT /* * Special case for leftmost character of the displayed area. * Only half of a double-width character may be visible. */ if (j == pmincol && j > 0 && isWidecExt(ch)) { SetChar(ch, L(' '), AttrOf(oline->text[j - 1])); } #endif if (!CharEq(ch, nline->text[n])) { nline->text[n] = ch; CHANGED_CELL(nline, n); } } #if USE_SCROLL_HINTS if (wide) { int nind = m + displaced; if (oline->oldindex < 0 || nind < sminrow || nind > smaxrow) { nind = _NEWINDEX; } else if (displaced) { register struct ldat *pline = &CurScreen(sp)->_line[nind]; for (j = 0; j <= my_len; j++) { int k = NewScreen(sp)->_maxx - j; if (pline->text[j] != nline->text[j] || pline->text[k] != nline->text[k]) { nind = _NEWINDEX; break; } } } nline->oldindex = nind; } #endif /* USE_SCROLL_HINTS */ oline->firstchar = oline->lastchar = _NOCHANGE; if_USE_SCROLL_HINTS(oline->oldindex = i); } /* * Clean up debris from scrolling or resizing the pad, so we do not * accidentally pick up the index value during the next call to this * procedure. The only rows that should have an index value are those * that are displayed during this cycle. */ #if USE_SCROLL_HINTS for (i = pminrow - 1; (i >= 0) && (win->_line[i].oldindex >= 0); i--) win->_line[i].oldindex = _NEWINDEX; for (i = pmaxrow + 1; (i <= win->_maxy) && (win->_line[i].oldindex >= 0); i++) win->_line[i].oldindex = _NEWINDEX; #endif win->_begx = smincol; win->_begy = sminrow; if (win->_clear) { win->_clear = FALSE; NewScreen(sp)->_clear = TRUE; } /* * Use the pad's current position, if it will be visible. * If not, don't do anything; it's not an error. */ if (win->_leaveok == FALSE && win->_cury >= pminrow && win->_curx >= pmincol && win->_cury <= pmaxrow && win->_curx <= pmaxcol) { NewScreen(sp)->_cury = win->_cury - pminrow + win->_begy + win->_yoffset; NewScreen(sp)->_curx = win->_curx - pmincol + win->_begx; } NewScreen(sp)->_leaveok = win->_leaveok; win->_flags &= ~_HASMOVED; /* * Update our cache of the line-numbers that we displayed from the pad. * We will use this on subsequent calls to this function to derive * values to stuff into 'oldindex[]' -- for scrolling optimization. */ win->_pad._pad_y = pminrow; win->_pad._pad_x = pmincol; win->_pad._pad_top = sminrow; win->_pad._pad_left = smincol; win->_pad._pad_bottom = smaxrow; win->_pad._pad_right = smaxcol; returnCode(OK); }
mvcur(int yold, int xold, int ynew, int xnew) /* optimized cursor move from (yold, xold) to (ynew, xnew) */ { NCURSES_CH_T oldattr; int code; TR(TRACE_CALLS | TRACE_MOVE, (T_CALLED("mvcur(%d,%d,%d,%d)"), yold, xold, ynew, xnew)); if (SP == 0) { code = ERR; } else if (yold == ynew && xold == xnew) { code = OK; } else { /* * Most work here is rounding for terminal boundaries getting the * column position implied by wraparound or the lack thereof and * rolling up the screen to get ynew on the screen. */ if (xnew >= screen_columns) { ynew += xnew / screen_columns; xnew %= screen_columns; } /* * Force restore even if msgr is on when we're in an alternate * character set -- these have a strong tendency to screw up the CR & * LF used for local character motions! */ oldattr = SCREEN_ATTRS(SP); if ((AttrOf(oldattr) & A_ALTCHARSET) || (AttrOf(oldattr) && !move_standout_mode)) { TR(TRACE_CHARPUT, ("turning off (%#lx) %s before move", (unsigned long) AttrOf(oldattr), _traceattr(AttrOf(oldattr)))); (void) VIDATTR(A_NORMAL, 0); } if (xold >= screen_columns) { int l; if (SP->_nl) { l = (xold + 1) / screen_columns; yold += l; if (yold >= screen_lines) l -= (yold - screen_lines - 1); if (l > 0) { if (carriage_return) { TPUTS_TRACE("carriage_return"); putp(carriage_return); } else _nc_outch('\r'); xold = 0; while (l > 0) { if (newline) { TPUTS_TRACE("newline"); putp(newline); } else _nc_outch('\n'); l--; } } } else { /* * If caller set nonl(), we cannot really use newlines to * position to the next row. */ xold = -1; yold = -1; } } if (yold > screen_lines - 1) yold = screen_lines - 1; if (ynew > screen_lines - 1) ynew = screen_lines - 1; /* destination location is on screen now */ code = onscreen_mvcur(yold, xold, ynew, xnew, TRUE); /* * Restore attributes if we disabled them before moving. */ if (!SameAttrOf(oldattr, SCREEN_ATTRS(SP))) { TR(TRACE_CHARPUT, ("turning on (%#lx) %s after move", (unsigned long) AttrOf(oldattr), _traceattr(AttrOf(oldattr)))); (void) VIDATTR(AttrOf(oldattr), GetPair(oldattr)); } } returnCode(code); }
static #if !USE_WIDEC_SUPPORT /* cannot be inline if it is recursive */ NCURSES_INLINE #endif int waddch_literal(WINDOW *win, NCURSES_CH_T ch) { int x; int y; struct ldat *line; x = win->_curx; y = win->_cury; CHECK_POSITION(win, x, y); ch = render_char(win, ch); line = win->_line + y; CHANGED_CELL(line, x); /* * Build up multibyte characters until we have a wide-character. */ #if NCURSES_SP_FUNCS #define DeriveSP() SCREEN *sp = _nc_screen_of(win); #else #define DeriveSP() /*nothing */ #endif if_WIDEC({ DeriveSP(); if (WINDOW_EXT(win, addch_used) != 0 || !Charable(ch)) { int len = _nc_build_wch(win, CHREF(ch)); if (len >= -1) { attr_t attr = AttrOf(ch); /* handle EILSEQ (i.e., when len >= -1) */ if (len == -1 && is8bits(CharOf(ch))) { int rc = OK; const char *s = NCURSES_SP_NAME(unctrl) (NCURSES_SP_ARGx (chtype) CharOf(ch)); if (s[1] != '\0') { while (*s != '\0') { rc = waddch(win, UChar(*s) | attr); if (rc != OK) break; ++s; } return rc; } } if (len == -1) return waddch(win, ' ' | attr); } else { return OK; } } });
char *_traceattr2(int bufnum, attr_t newmode) { char *buf = _nc_trace_buf(bufnum, BUFSIZ); char *tmp = buf; static const struct {unsigned int val; const char *name;} names[] = { { A_STANDOUT, "A_STANDOUT" }, { A_UNDERLINE, "A_UNDERLINE" }, { A_REVERSE, "A_REVERSE" }, { A_BLINK, "A_BLINK" }, { A_DIM, "A_DIM" }, { A_BOLD, "A_BOLD" }, { A_ALTCHARSET, "A_ALTCHARSET" }, { A_INVIS, "A_INVIS" }, { A_PROTECT, "A_PROTECT" }, { A_CHARTEXT, "A_CHARTEXT" }, { A_NORMAL, "A_NORMAL" }, { A_COLOR, "A_COLOR" }, }, colors[] = { { COLOR_BLACK, "COLOR_BLACK" }, { COLOR_RED, "COLOR_RED" }, { COLOR_GREEN, "COLOR_GREEN" }, { COLOR_YELLOW, "COLOR_YELLOW" }, { COLOR_BLUE, "COLOR_BLUE" }, { COLOR_MAGENTA, "COLOR_MAGENTA" }, { COLOR_CYAN, "COLOR_CYAN" }, { COLOR_WHITE, "COLOR_WHITE" }, }; size_t n; unsigned save_nc_tracing = _nc_tracing; _nc_tracing = 0; strcpy(tmp++, "{"); for (n = 0; n < SIZEOF(names); n++) { if ((newmode & names[n].val) != 0) { if (buf[1] != '\0') strcat(tmp, "|"); strcat(tmp, names[n].name); tmp += strlen(tmp); if (names[n].val == A_COLOR) { short pairnum = PAIR_NUMBER(newmode); short fg, bg; if (pair_content(pairnum, &fg, &bg) == OK) (void) sprintf(tmp, "{%d = {%s, %s}}", pairnum, COLOR_OF(fg), COLOR_OF(bg) ); else (void) sprintf(tmp, "{%d}", pairnum); } } } if (AttrOf(newmode) == A_NORMAL) { if (buf[1] != '\0') strcat(tmp, "|"); strcat(tmp, "A_NORMAL"); } _nc_tracing = save_nc_tracing; return (strcat(buf,"}")); }
/* * Write the soft labels to the soft-key window. */ static void slk_intern_refresh(SCREEN *sp) { int i; int fmt; SLK *slk; int numlab; if (sp == 0) return; slk = sp->_slk; fmt = sp->slk_format; numlab = NumLabels; if (slk->hidden) return; for (i = 0; i < slk->labcnt; i++) { if (slk->dirty || slk->ent[i].dirty) { if (slk->ent[i].visible) { if (numlab > 0 && SLK_STDFMT(fmt)) { #ifdef USE_TERM_DRIVER CallDriver_2(sp, hwlabel, i + 1, slk->ent[i].form_text); #else if (i < num_labels) { TPUTS_TRACE("plab_norm"); putp(TPARM_2(plab_norm, i + 1, slk->ent[i].form_text)); } #endif } else { if (fmt == 4) slk_paint_info(slk->win); wmove(slk->win, SLK_LINES(fmt) - 1, slk->ent[i].ent_x); if (sp->_slk) { (void) wattrset(slk->win, AttrOf(sp->_slk->attr)); } waddstr(slk->win, slk->ent[i].form_text); /* if we simulate SLK's, it's looking much more natural to use the current ATTRIBUTE also for the label window */ (void) wattrset(slk->win, WINDOW_ATTRS(StdScreen(sp))); } } slk->ent[i].dirty = FALSE; } } slk->dirty = FALSE; if (numlab > 0) { #ifdef USE_TERM_DRIVER CallDriver_1(sp, hwlabelOnOff, slk->hidden ? FALSE : TRUE); #else if (slk->hidden) { TPUTS_TRACE("label_off"); putp(label_off); } else { TPUTS_TRACE("label_on"); putp(label_on); } #endif } }
static inline int waddch_nosync(WINDOW *win, const chtype ch) /* the workhorse function -- add a character to the given window */ { int x, y; int t; const char *s; if ((ch & A_ALTCHARSET) || ((t = TextOf(ch)) > 127) || ((s = unctrl(t))[1] == 0)) return waddch_literal(win, ch); x = win->_curx; y = win->_cury; switch (t) { case '\t': x += (TABSIZE-(x%TABSIZE)); /* * Space-fill the tab on the bottom line so that we'll get the * "correct" cursor position. */ if ((! win->_scroll && (y == win->_regbottom)) || (x <= win->_maxx)) { chtype blank = (' ' | AttrOf(ch)); while (win->_curx < x) { if (waddch_literal(win, blank) == ERR) return(ERR); } break; } else { wclrtoeol(win); win->_flags |= _WRAPPED; if (++y > win->_regbottom) { x = win->_maxx; y--; if (win->_scroll) { scroll(win); x = 0; } } else { x = 0; } } break; case '\n': wclrtoeol(win); if (++y > win->_regbottom) { y--; if (win->_scroll) scroll(win); else return (ERR); } /* FALLTHRU */ case '\r': x = 0; win->_flags &= ~_WRAPPED; break; case '\b': if (x == 0) return (OK); x--; win->_flags &= ~_WRAPPED; break; default: while (*s) if (waddch_literal(win, (*s++)|AttrOf(ch)) == ERR) return ERR; return(OK); } win->_curx = x; win->_cury = y; return(OK); }
copywin(const WINDOW *src, WINDOW *dst, int sminrow, int smincol, int dminrow, int dmincol, int dmaxrow, int dmaxcol, int over) { int rc = ERR; int sx, sy, dx, dy; bool touched; attr_t bk; attr_t mask; T((T_CALLED("copywin(%p, %p, %d, %d, %d, %d, %d, %d, %d)"), src, dst, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol, over)); if (src && dst) { _nc_lock_global(curses); bk = AttrOf(dst->_nc_bkgd); mask = ~(attr_t) ((bk & A_COLOR) ? A_COLOR : 0); /* make sure rectangle exists in source */ if ((sminrow + dmaxrow - dminrow) <= (src->_maxy + 1) && (smincol + dmaxcol - dmincol) <= (src->_maxx + 1)) { T(("rectangle exists in source")); /* make sure rectangle fits in destination */ if (dmaxrow <= dst->_maxy && dmaxcol <= dst->_maxx) { T(("rectangle fits in destination")); for (dy = dminrow, sy = sminrow; dy <= dmaxrow; sy++, dy++) { touched = FALSE; for (dx = dmincol, sx = smincol; dx <= dmaxcol; sx++, dx++) { if (over) { if ((CharOf(src->_line[sy].text[sx]) != L(' ')) && (!CharEq(dst->_line[dy].text[dx], src->_line[sy].text[sx]))) { dst->_line[dy].text[dx] = src->_line[sy].text[sx]; SetAttr(dst->_line[dy].text[dx], ((AttrOf(src->_line[sy].text[sx]) & mask) | bk)); touched = TRUE; } } else { if (!CharEq(dst->_line[dy].text[dx], src->_line[sy].text[sx])) { dst->_line[dy].text[dx] = src->_line[sy].text[sx]; touched = TRUE; } } } if (touched) { touchline(dst, dminrow, (dmaxrow - dminrow + 1)); } } T(("finished copywin")); rc = OK; } } _nc_unlock_global(curses); } returnCode(rc); }
static int relative_move(string_desc * target, int from_y, int from_x, int to_y, int to_x, bool ovw) /* move via local motions (cuu/cuu1/cud/cud1/cub1/cub/cuf1/cuf/vpa/hpa) */ { string_desc save; int n, vcost = 0, hcost = 0; (void) _nc_str_copy(&save, target); if (to_y != from_y) { vcost = INFINITY; if (row_address != 0 && _nc_safe_strcat(target, tparm(row_address, to_y))) { vcost = SP->_vpa_cost; } if (to_y > from_y) { n = (to_y - from_y); if (parm_down_cursor && SP->_cud_cost < vcost && _nc_safe_strcat(_nc_str_copy(target, &save), tparm(parm_down_cursor, n))) { vcost = SP->_cud_cost; } if (cursor_down && (*cursor_down != '\n' || SP->_nl) && (n * SP->_cud1_cost < vcost)) { vcost = repeated_append(_nc_str_copy(target, &save), 0, SP->_cud1_cost, n, cursor_down); } } else { /* (to_y < from_y) */ n = (from_y - to_y); if (parm_up_cursor && SP->_cup_cost < vcost && _nc_safe_strcat(_nc_str_copy(target, &save), tparm(parm_up_cursor, n))) { vcost = SP->_cup_cost; } if (cursor_up && (n * SP->_cuu1_cost < vcost)) { vcost = repeated_append(_nc_str_copy(target, &save), 0, SP->_cuu1_cost, n, cursor_up); } } if (vcost == INFINITY) return (INFINITY); } save = *target; if (to_x != from_x) { char str[OPT_SIZE]; string_desc check; hcost = INFINITY; if (column_address && _nc_safe_strcat(_nc_str_copy(target, &save), tparm(column_address, to_x))) { hcost = SP->_hpa_cost; } if (to_x > from_x) { n = to_x - from_x; if (parm_right_cursor && SP->_cuf_cost < hcost && _nc_safe_strcat(_nc_str_copy(target, &save), tparm(parm_right_cursor, n))) { hcost = SP->_cuf_cost; } if (cursor_right) { int lhcost = 0; (void) _nc_str_init(&check, str, sizeof(str)); #if USE_HARD_TABS /* use hard tabs, if we have them, to do as much as possible */ if (init_tabs > 0 && tab) { int nxt, fr; for (fr = from_x; (nxt = NEXTTAB(fr)) <= to_x; fr = nxt) { lhcost = repeated_append(&check, lhcost, SP->_ht_cost, 1, tab); if (lhcost == INFINITY) break; } n = to_x - fr; from_x = fr; } #endif /* USE_HARD_TABS */ #if defined(REAL_ATTR) && defined(WANT_CHAR) if (n <= 0 || n >= (int) check.s_size) ovw = FALSE; #if BSD_TPUTS /* * If we're allowing BSD-style padding in tputs, don't generate * a string with a leading digit. Otherwise, that will be * interpreted as a padding value rather than sent to the * screen. */ if (ovw && n > 0 && n < (int) check.s_size && vcost == 0 && str[0] == '\0' && isdigit(CharOf(WANT_CHAR(to_y, from_x)))) ovw = FALSE; #endif /* * If we have no attribute changes, overwrite is cheaper. * Note: must suppress this by passing in ovw = FALSE whenever * WANT_CHAR would return invalid data. In particular, this * is true between the time a hardware scroll has been done * and the time the structure WANT_CHAR would access has been * updated. */ if (ovw) { int i; for (i = 0; i < n; i++) { NCURSES_CH_T ch = WANT_CHAR(to_y, from_x + i); if (AttrOf(ch) != CURRENT_ATTR #if USE_WIDEC_SUPPORT || !Charable(ch) #endif ) { ovw = FALSE; break; } } } if (ovw) { int i; for (i = 0; i < n; i++) *check.s_tail++ = CharOf(WANT_CHAR(to_y, from_x + i)); *check.s_tail = '\0'; check.s_size -= n; lhcost += n * SP->_char_padding; } else #endif /* defined(REAL_ATTR) && defined(WANT_CHAR) */ { lhcost = repeated_append(&check, lhcost, SP->_cuf1_cost, n, cursor_right); } if (lhcost < hcost && _nc_safe_strcat(_nc_str_copy(target, &save), str)) { hcost = lhcost; } } } else { /* (to_x < from_x) */ n = from_x - to_x; if (parm_left_cursor && SP->_cub_cost < hcost && _nc_safe_strcat(_nc_str_copy(target, &save), tparm(parm_left_cursor, n))) { hcost = SP->_cub_cost; } if (cursor_left) { int lhcost = 0; (void) _nc_str_init(&check, str, sizeof(str)); #if USE_HARD_TABS if (init_tabs > 0 && back_tab) { int nxt, fr; for (fr = from_x; (nxt = LASTTAB(fr)) >= to_x; fr = nxt) { lhcost = repeated_append(&check, lhcost, SP->_cbt_cost, 1, back_tab); if (lhcost == INFINITY) break; } n = fr - to_x; } #endif /* USE_HARD_TABS */ lhcost = repeated_append(&check, lhcost, SP->_cub1_cost, n, cursor_left); if (lhcost < hcost && _nc_safe_strcat(_nc_str_copy(target, &save), str)) { hcost = lhcost; } } } if (hcost == INFINITY) return (INFINITY); } return (vcost + hcost); }